FE: delay UI_DEFAULT_PAGE_SIZE setting check after cahce rebuilt #1181

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2025-11-29 15:45:28 +11:00
parent 0d81315809
commit 8586c5a307
2 changed files with 206 additions and 204 deletions

View File

@@ -1,7 +1,7 @@
<!-- <!--
#---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------#
# NetAlertX # # NetAlertX #
# Open Source Network Guard / WIFI & LAN intrusion detector # # Open Source Network Guard / WIFI & LAN intrusion detector #
# # # #
# devices.php - Front module. Devices list page # # devices.php - Front module. Devices list page #
#---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------#
@@ -15,7 +15,7 @@
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
// check permissions // check permissions
// Use environment-aware paths with fallback to legacy locations // Use environment-aware paths with fallback to legacy locations
$dbFolderPath = rtrim(getenv('NETALERTX_DB') ?: '/data/db', '/'); $dbFolderPath = rtrim(getenv('NETALERTX_DB') ?: '/data/db', '/');
@@ -36,7 +36,7 @@
?> ?>
<!-- ----------------------------------------------------------------------- --> <!-- ----------------------------------------------------------------------- -->
<!-- Page ------------------------------------------------------------------ --> <!-- Page ------------------------------------------------------------------ -->
<div class="content-wrapper"> <div class="content-wrapper">
@@ -55,15 +55,15 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="box" id="clients"> <div class="box" id="clients">
<div class="box-header "> <div class="box-header ">
<h3 class="box-title col-md-12"><?= lang('Device_Shortcut_OnlineChart');?> </h3> <h3 class="box-title col-md-12"><?= lang('Device_Shortcut_OnlineChart');?> </h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="chart"> <div class="chart">
<script src="lib/chart.js/Chart.js?v=<?php include 'php/templates/version.php'; ?>"></script> <script src="lib/chart.js/Chart.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<!-- presence chart --> <!-- presence chart -->
<?php <?php
require 'php/components/graph_online_history.php'; require 'php/components/graph_online_history.php';
?> ?>
</div> </div>
</div> </div>
<!-- /.box-body --> <!-- /.box-body -->
@@ -74,7 +74,7 @@
<!-- Device Filters ------------------------------------------------------- --> <!-- Device Filters ------------------------------------------------------- -->
<div class="box box-aqua hidden" id="columnFiltersWrap"> <div class="box box-aqua hidden" id="columnFiltersWrap">
<div class="box-header "> <div class="box-header ">
<h3 class="box-title col-md-12"><?= lang('Devices_Filters');?> </h3> <h3 class="box-title col-md-12"><?= lang('Devices_Filters');?> </h3>
</div> </div>
<!-- Placeholder ------------------------------------------------------- --> <!-- Placeholder ------------------------------------------------------- -->
<div id="columnFilters" ></div> <div id="columnFilters" ></div>
@@ -88,8 +88,8 @@
<!-- box-header --> <!-- box-header -->
<div class="box-header"> <div class="box-header">
<div class=" col-sm-8 "> <div class=" col-sm-8 ">
<h3 id="tableDevicesTitle" class="box-title text-gray "></h3> <h3 id="tableDevicesTitle" class="box-title text-gray "></h3>
</div> </div>
<div class="dummyDevice col-sm-4 "> <div class="dummyDevice col-sm-4 ">
<span id="multiEditPlc"> <span id="multiEditPlc">
<!-- multi edit button placeholder --> <!-- multi edit button placeholder -->
@@ -104,8 +104,8 @@
<div class="box-body table-responsive"> <div class="box-body table-responsive">
<table id="tableDevices" class="table table-bordered table-hover table-striped"> <table id="tableDevices" class="table table-bordered table-hover table-striped">
<thead> <thead>
<tr> <tr>
</tr> </tr>
</thead> </thead>
</table> </table>
@@ -122,7 +122,7 @@
<!-- ----------------------------------------------------------------------- --> <!-- ----------------------------------------------------------------------- -->
</section> </section>
<!-- /.content --> <!-- /.content -->
</div> </div>
<!-- /.content-wrapper --> <!-- /.content-wrapper -->
@@ -136,9 +136,9 @@
<!-- page script ----------------------------------------------------------- --> <!-- page script ----------------------------------------------------------- -->
<script> <script>
var deviceStatus = 'all'; var deviceStatus = 'all';
var tableRows = getCache ("nax_parTableRows") == "" ? parseInt(getSetting("UI_DEFAULT_PAGE_SIZE")) : getCache ("nax_parTableRows") ;
var tableOrder = getCache ("nax_parTableOrder") == "" ? [[3,'desc'], [0,'asc']] : JSON.parse(getCache ("nax_parTableOrder")) ; var tableOrder = getCache ("nax_parTableOrder") == "" ? [[3,'desc'], [0,'asc']] : JSON.parse(getCache ("nax_parTableOrder")) ;
var tableColumnHide = []; var tableColumnHide = [];
var tableColumnOrder = []; var tableColumnOrder = [];
var tableColumnVisible = []; var tableColumnVisible = [];
@@ -161,7 +161,7 @@ function main () {
//initialize the table headers in the correct order //initialize the table headers in the correct order
var availableColumns = getSettingOptions("UI_device_columns").split(","); var availableColumns = getSettingOptions("UI_device_columns").split(",");
headersDefaultOrder = availableColumns.map(val => getString(val)); headersDefaultOrder = availableColumns.map(val => getString(val));
var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"')); var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
@@ -190,10 +190,10 @@ function main () {
// Initialize components with parameters // Initialize components with parameters
initializeDatatable(getUrlAnchor('my_devices')); initializeDatatable(getUrlAnchor('my_devices'));
// check if data outdated and show spinner if so // check if data outdated and show spinner if so
handleLoadingDialog() handleLoadingDialog()
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -202,7 +202,7 @@ function mapIndx(oldIndex)
{ {
// console.log(oldIndex); // console.log(oldIndex);
// console.log(tableColumnOrder); // console.log(tableColumnOrder);
for(i=0;i<tableColumnOrder.length;i++) for(i=0;i<tableColumnOrder.length;i++)
{ {
if(tableColumnOrder[i] == oldIndex) if(tableColumnOrder[i] == oldIndex)
@@ -311,7 +311,7 @@ function processDeviceTotals(devicesData) {
} }
}); });
// Render info boxes/tile cards // Render info boxes/tile cards
renderInfoboxes(dataArray); renderInfoboxes(dataArray);
} }
@@ -350,9 +350,9 @@ function initFilters() {
nocache: Date.now() // Prevent caching with a timestamp nocache: Date.now() // Prevent caching with a timestamp
}, },
success: function(response) { success: function(response) {
if (response && response.data) { if (response && response.data) {
let resultJSON = response.data; let resultJSON = response.data;
// Save the result to cache // Save the result to cache
setCache("devicesFilters", JSON.stringify(resultJSON)); setCache("devicesFilters", JSON.stringify(resultJSON));
@@ -381,7 +381,7 @@ function initFilters() {
}); });
// Filter resultJSON to include only entries with columnName in columnFilters // Filter resultJSON to include only entries with columnName in columnFilters
resultJSON = resultJSON.filter(entry => resultJSON = resultJSON.filter(entry =>
columnFilters.some(filter => filter[0] === entry.columnName) columnFilters.some(filter => filter[0] === entry.columnName)
); );
@@ -451,7 +451,7 @@ function initFilters() {
function renderFilters(customData) { function renderFilters(customData) {
// console.log(JSON.stringify(customData)); // console.log(JSON.stringify(customData));
// Load filter data from the JSON file // Load filter data from the JSON file
$.ajax({ $.ajax({
url: 'php/components/devices_filters.php', // PHP script URL url: 'php/components/devices_filters.php', // PHP script URL
@@ -471,7 +471,7 @@ function renderFilters(customData) {
// Update DataTable with the new filters or search value (if applicable) // Update DataTable with the new filters or search value (if applicable)
$('#tableDevices').DataTable().draw(); $('#tableDevices').DataTable().draw();
// Optionally, apply column filters (if using filters for individual columns) // Optionally, apply column filters (if using filters for individual columns)
const table = $('#tableDevices').DataTable(); const table = $('#tableDevices').DataTable();
table.columnFilters = columnFilters; // Apply your column filters logic table.columnFilters = columnFilters; // Apply your column filters logic
@@ -493,11 +493,11 @@ function collectFilters() {
// Loop through each filter group // Loop through each filter group
document.querySelectorAll('.filter-group').forEach(filterGroup => { document.querySelectorAll('.filter-group').forEach(filterGroup => {
const dropdown = filterGroup.querySelector('.filter-dropdown'); const dropdown = filterGroup.querySelector('.filter-dropdown');
if (dropdown) { if (dropdown) {
const filterColumn = dropdown.getAttribute('data-column'); const filterColumn = dropdown.getAttribute('data-column');
const filterValue = dropdown.value; const filterValue = dropdown.value;
if (filterValue && filterColumn) { if (filterValue && filterColumn) {
columnFilters.push({ columnFilters.push({
filterColumn: filterColumn, filterColumn: filterColumn,
@@ -548,7 +548,7 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
"devReqNicsOnline" // 29 "devReqNicsOnline" // 29
]; ];
// console.log("OrderBy: " + columnNames[tableColumnOrder[index]]); // console.log("OrderBy: " + columnNames[tableColumnOrder[index]]);
return columnNames[tableColumnOrder[index]] || null; return columnNames[tableColumnOrder[index]] || null;
} }
@@ -557,12 +557,15 @@ function mapColumnIndexToFieldName(index, tableColumnVisible) {
// --------------------------------------------------------- // ---------------------------------------------------------
// Initializes the main devices list datatable // Initializes the main devices list datatable
function initializeDatatable (status) { function initializeDatatable (status) {
if(!status) if(!status)
{ {
status = 'my_devices' status = 'my_devices'
} }
// retrieve page size
var tableRows = getCache ("nax_parTableRows") == "" ? parseInt(getSetting("UI_DEFAULT_PAGE_SIZE")) : getCache ("nax_parTableRows") ;
// Save status selected // Save status selected
deviceStatus = status; deviceStatus = status;
@@ -579,7 +582,7 @@ function initializeDatatable (status) {
case 'all_devices': tableTitle = getString('Gen_All_Devices'); color = 'gray'; break; case 'all_devices': tableTitle = getString('Gen_All_Devices'); color = 'gray'; break;
case 'network_devices': tableTitle = getString('Network_Devices'); color = 'aqua'; break; case 'network_devices': tableTitle = getString('Network_Devices'); color = 'aqua'; break;
default: tableTitle = getString('Device_Shortcut_Devices'); color = 'gray'; break; default: tableTitle = getString('Device_Shortcut_Devices'); color = 'gray'; break;
} }
// Set title and color // Set title and color
$('#tableDevicesTitle')[0].className = 'box-title text-'+ color; $('#tableDevicesTitle')[0].className = 'box-title text-'+ color;
@@ -588,23 +591,23 @@ function initializeDatatable (status) {
// render table headers // render table headers
html = ''; html = '';
for(index = 0; index < tableColumnOrder.length; index++) for(index = 0; index < tableColumnOrder.length; index++)
{ {
html += '<th>' + headersDefaultOrder[tableColumnOrder[index]] + '</th>'; html += '<th>' + headersDefaultOrder[tableColumnOrder[index]] + '</th>';
} }
$('#tableDevices tr').html(html); $('#tableDevices tr').html(html);
hideUIelements("UI_DEV_SECTIONS") hideUIelements("UI_DEV_SECTIONS")
for(i = 0; i < tableColumnOrder.length; i++) for(i = 0; i < tableColumnOrder.length; i++)
{ {
// hide this column if not in the tableColumnVisible variable (we need to keep the MAC address (index 11) for functionality reasons) // hide this column if not in the tableColumnVisible variable (we need to keep the MAC address (index 11) for functionality reasons)
if(tableColumnVisible.includes(tableColumnOrder[i]) == false) if(tableColumnVisible.includes(tableColumnOrder[i]) == false)
{ {
tableColumnHide.push(mapIndx(tableColumnOrder[i])); tableColumnHide.push(mapIndx(tableColumnOrder[i]));
} }
} }
var table = $('#tableDevices').DataTable({ var table = $('#tableDevices').DataTable({
@@ -690,7 +693,7 @@ function initializeDatatable (status) {
"status": deviceStatus, "status": deviceStatus,
"filters" : columnFilters "filters" : columnFilters
} }
} }
}; };
@@ -766,8 +769,8 @@ function initializeDatatable (status) {
// Parameters // Parameters
'pageLength' : tableRows, 'pageLength' : tableRows,
'order' : tableOrder, 'order' : tableOrder,
'select' : true, // Enable selection 'select' : true, // Enable selection
'fixedHeader': true, 'fixedHeader': true,
'fixedHeader': { 'fixedHeader': {
@@ -776,19 +779,19 @@ function initializeDatatable (status) {
}, },
'columnDefs' : [ 'columnDefs' : [
{visible: false, targets: tableColumnHide }, {visible: false, targets: tableColumnHide },
{className: 'text-center', targets: [mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] }, {className: 'text-center', targets: [mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] },
{className: 'iconColumn text-center', targets: [mapIndx(3)]}, {className: 'iconColumn text-center', targets: [mapIndx(3)]},
{width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15), mapIndx(27)] }, {width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15), mapIndx(27)] },
{width: '85px', targets: [mapIndx(9)] }, {width: '85px', targets: [mapIndx(9)] },
{width: '30px', targets: [mapIndx(3), mapIndx(10), mapIndx(13), mapIndx(18)] }, {width: '30px', targets: [mapIndx(3), mapIndx(10), mapIndx(13), mapIndx(18)] },
{orderData: [mapIndx(12)], targets: mapIndx(8) }, {orderData: [mapIndx(12)], targets: mapIndx(8) },
// Device Name and FQDN // Device Name and FQDN
{targets: [mapIndx(0), mapIndx(27)], {targets: [mapIndx(0), mapIndx(27)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
// console.log(cellData) // console.log(cellData)
$(td).html ( $(td).html (
`<b class="anonymizeDev " `<b class="anonymizeDev "
> >
@@ -811,9 +814,9 @@ function initializeDatatable (status) {
); );
} }, } },
// Connected Devices // Connected Devices
{targets: [mapIndx(15)], {targets: [mapIndx(15)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
// check if this is a network device // check if this is a network device
if(getSetting("NETWORK_DEVICE_TYPES").includes(`'${rowData[mapIndx(2)]}'`) ) if(getSetting("NETWORK_DEVICE_TYPES").includes(`'${rowData[mapIndx(2)]}'`) )
{ {
@@ -823,13 +826,13 @@ function initializeDatatable (status) {
{ {
$(td).html (`<i class="fa-solid fa-xmark" title="${getString("Device_Table_Not_Network_Device")}"></i>`) $(td).html (`<i class="fa-solid fa-xmark" title="${getString("Device_Table_Not_Network_Device")}"></i>`)
} }
} }, } },
// Icon // Icon
{targets: [mapIndx(3)], {targets: [mapIndx(3)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){ if (!emptyArr.includes(cellData)){
$(td).html (atob(cellData)); $(td).html (atob(cellData));
} else { } else {
@@ -837,7 +840,7 @@ function initializeDatatable (status) {
} }
} }, } },
// Full MAC // Full MAC
{targets: [mapIndx(11)], {targets: [mapIndx(11)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){ if (!emptyArr.includes(cellData)){
@@ -846,8 +849,8 @@ function initializeDatatable (status) {
$(td).html (''); $(td).html ('');
} }
} }, } },
// IP address // IP address
{targets: [mapIndx(8)], {targets: [mapIndx(8)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){ if (!emptyArr.includes(cellData)){
@@ -864,9 +867,9 @@ function initializeDatatable (status) {
} else { } else {
$(td).html (''); $(td).html ('');
} }
} }
}, },
// IP address (ordeable) // IP address (ordeable)
{targets: [mapIndx(12)], {targets: [mapIndx(12)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){ if (!emptyArr.includes(cellData)){
@@ -874,10 +877,10 @@ function initializeDatatable (status) {
} else { } else {
$(td).html (''); $(td).html ('');
} }
} }
}, },
// Custom Properties // Custom Properties
{targets: [mapIndx(26)], {targets: [mapIndx(26)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){ if (!emptyArr.includes(cellData)){
@@ -885,10 +888,10 @@ function initializeDatatable (status) {
} else { } else {
$(td).html (''); $(td).html ('');
} }
} }
}, },
// Favorite // Favorite
{targets: [mapIndx(4)], {targets: [mapIndx(4)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){ if (cellData == 1){
@@ -897,8 +900,8 @@ function initializeDatatable (status) {
$(td).html (''); $(td).html ('');
} }
} }, } },
// Dates // Dates
{targets: [mapIndx(6), mapIndx(7)], {targets: [mapIndx(6), mapIndx(7)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
var result = cellData.toString(); // Convert to string var result = cellData.toString(); // Convert to string
@@ -908,7 +911,7 @@ function initializeDatatable (status) {
$(td).html (translateHTMLcodes (result)); $(td).html (translateHTMLcodes (result));
} }, } },
// Random MAC // Random MAC
{targets: [mapIndx(9)], {targets: [mapIndx(9)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
// console.log(cellData) // console.log(cellData)
@@ -919,7 +922,7 @@ function initializeDatatable (status) {
} }
} }, } },
// Parent Mac // Parent Mac
{targets: [mapIndx(14)], {targets: [mapIndx(14)],
'createdCell': function (td, cellData, rowData, row, col) { 'createdCell': function (td, cellData, rowData, row, col) {
if (!isValidMac(cellData)) { if (!isValidMac(cellData)) {
@@ -938,13 +941,13 @@ function initializeDatatable (status) {
const chipHtml = renderDeviceLink(data, spanWrap, true); // pass the td as container const chipHtml = renderDeviceLink(data, spanWrap, true); // pass the td as container
$(spanWrap).append(chipHtml); $(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) {
tmp_devPresentLastScan = rowData[mapIndx(24)] tmp_devPresentLastScan = rowData[mapIndx(24)]
tmp_devAlertDown = rowData[mapIndx(25)] tmp_devAlertDown = rowData[mapIndx(25)]
@@ -954,11 +957,11 @@ function initializeDatatable (status) {
rowData[mapIndx(11)], // MAC rowData[mapIndx(11)], // MAC
cellData // optional text cellData // optional text
); );
$(td).html (`<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.text}</a>`); $(td).html (`<a href="${badge.url}" class="badge ${badge.cssClass}">${badge.iconHtml} ${badge.text}</a>`);
} }, } },
], ],
// Processing // Processing
'processing' : true, 'processing' : true,
'language' : { 'language' : {
@@ -978,7 +981,7 @@ function initializeDatatable (status) {
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) { $('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
setCache ("nax_parTableRows", len, 129600); // save for 90 days setCache ("nax_parTableRows", len, 129600); // save for 90 days
} ); } );
$('#tableDevices').on( 'order.dt', function () { $('#tableDevices').on( 'order.dt', function () {
setCache ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days setCache ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
} ); } );
@@ -998,7 +1001,7 @@ function initializeDatatable (status) {
// Toggle visibility of element with ID 'multiEdit' // Toggle visibility of element with ID 'multiEdit'
$('#multiEdit').toggle(anyRowSelected); $('#multiEdit').toggle(anyRowSelected);
}, 100); }, 100);
}); });
// search only after idle // search only after idle
@@ -1014,59 +1017,59 @@ function initializeDatatable (status) {
}, debounceTime); }, debounceTime);
}); });
initHoverNodeInfo(); initHoverNodeInfo();
hideSpinner(); hideSpinner();
}, },
createdRow: function(row, data, dataIndex) { createdRow: function(row, data, dataIndex) {
// add devMac to the table row // add devMac to the table row
$(row).attr('my-devMac', data[mapIndx(11)]); $(row).attr('my-devMac', data[mapIndx(11)]);
} }
}); });
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function handleLoadingDialog(needsReload = false) function handleLoadingDialog(needsReload = false)
{ {
// console.log(`needsReload: ${needsReload}`); // console.log(`needsReload: ${needsReload}`);
$.get('php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) { $.get('php/server/query_logs.php?file=execution_queue.log&nocache=' + Date.now(), function(data) {
if(data.includes("update_api|devices")) if(data.includes("update_api|devices"))
{ {
showSpinner("devices_old") showSpinner("devices_old")
setTimeout(handleLoadingDialog(true), 1000); setTimeout(handleLoadingDialog(true), 1000);
} else if (needsReload) } else if (needsReload)
{ {
location.reload(); location.reload();
}else }else
{ {
// hideSpinner(); // hideSpinner();
} }
}) })
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Function collects selected devices in the DataTable and redirects the user to // Function collects selected devices in the DataTable and redirects the user to
// the Miantenance section with a 'macs' query string identifying selected devices // the Miantenance section with a 'macs' query string identifying selected devices
function multiEditDevices() function multiEditDevices()
{ {
// get selected devices // get selected devices
var selectedDevicesDataTableData = $('#tableDevices').DataTable().rows({ selected: true, page: 'current' }).data().toArray(); var selectedDevicesDataTableData = $('#tableDevices').DataTable().rows({ selected: true, page: 'current' }).data().toArray();
console.log(selectedDevicesDataTableData); console.log(selectedDevicesDataTableData);
macs = "" macs = ""
for (var j = 0; j < selectedDevicesDataTableData.length; j++) { for (var j = 0; j < selectedDevicesDataTableData.length; j++) {
macs += selectedDevicesDataTableData[j][mapIndx(11)] + ","; // [11] == MAC macs += selectedDevicesDataTableData[j][mapIndx(11)] + ","; // [11] == MAC
} }
// redirect to the Maintenance section // redirect to the Maintenance section
@@ -1075,7 +1078,7 @@ function multiEditDevices()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Function collects shown devices from the DataTable // Function collects shown devices from the DataTable
function getMacsOfShownDevices() { function getMacsOfShownDevices() {
var table = $('#tableDevices').DataTable(); var table = $('#tableDevices').DataTable();
@@ -1096,15 +1099,15 @@ function getMacsOfShownDevices() {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Handle custom actions/properties on a device // Handle custom actions/properties on a device
function renderCustomProps(custProps, mac) { function renderCustomProps(custProps, mac) {
// Decode and parse the custom properties // Decode and parse the custom properties
if (!isBase64(custProps)) { if (!isBase64(custProps)) {
console.error(`Unable to decode CustomProps for ${mac}`); console.error(`Unable to decode CustomProps for ${mac}`);
console.error(custProps); console.error(custProps);
} else{ } else{
const props = JSON.parse(atob(custProps)); const props = JSON.parse(atob(custProps));
let html = ""; let html = "";
@@ -1150,13 +1153,13 @@ function renderCustomProps(custProps, mac) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Update cache with shown devices before navigating away // Update cache with shown devices before navigating away
window.addEventListener('beforeunload', function(event) { window.addEventListener('beforeunload', function(event) {
// Call your function here // Call your function here
macs = getMacsOfShownDevices(); macs = getMacsOfShownDevices();
setCache("ntx_visible_macs", macs) setCache("ntx_visible_macs", macs)
}); });
</script> </script>

View File

@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* NetAlertX * NetAlertX
* Open Source Network Guard / WIFI & LAN intrusion detector * Open Source Network Guard / WIFI & LAN intrusion detector
* *
* common.js - Front module. Common Javascript functions * common.js - Front module. Common Javascript functions
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
@@ -35,16 +35,16 @@ function getCache(key, noCookie = false)
// } // }
} }
return ""; return "";
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function setCache(key, data, expirationMinutes='') function setCache(key, data, expirationMinutes='')
{ {
localStorage.setItem(key, data); localStorage.setItem(key, data);
// // create cookie if expiration set to handle refresh of data // // create cookie if expiration set to handle refresh of data
// if (expirationMinutes != '') // if (expirationMinutes != '')
// { // {
// setCookie ('cache_session_expiry', 'OK', 1) // setCookie ('cache_session_expiry', 'OK', 1)
// } // }
@@ -57,7 +57,7 @@ function setCookie (cookie, value, expirationMinutes='') {
var expires = ''; var expires = '';
if (typeof expirationMinutes === 'number') { if (typeof expirationMinutes === 'number') {
expires = ';expires=' + new Date(Date.now() + expirationMinutes *60*1000).toUTCString(); expires = ';expires=' + new Date(Date.now() + expirationMinutes *60*1000).toUTCString();
} }
// Save Cookie // Save Cookie
document.cookie = cookie + "=" + value + expires; document.cookie = cookie + "=" + value + expires;
@@ -107,42 +107,42 @@ function deleteAllCookies() {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Get settings from the .json file generated by the python backend // Get settings from the .json file generated by the python backend
// and cache them, if available, with options // and cache them, if available, with options
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function cacheSettings() function cacheSettings()
{ {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(!getCache('cacheSettings_completed') === true) if(!getCache('cacheSettings_completed') === true)
{ {
$.get('php/server/query_json.php', { file: 'table_settings.json', nocache: Date.now() }, function(resSet) { $.get('php/server/query_json.php', { file: 'table_settings.json', nocache: Date.now() }, function(resSet) {
$.get('php/server/query_json.php', { file: 'plugins.json', nocache: Date.now() }, function(resPlug) { $.get('php/server/query_json.php', { file: 'plugins.json', nocache: Date.now() }, function(resPlug) {
pluginsData = resPlug["data"];
settingsData = resSet["data"];
settingsData.forEach((set) => { pluginsData = resPlug["data"];
settingsData = resSet["data"];
settingsData.forEach((set) => {
resolvedOptions = createArray(set.setOptions) resolvedOptions = createArray(set.setOptions)
resolvedOptionsOld = resolvedOptions resolvedOptionsOld = resolvedOptions
setPlugObj = {}; setPlugObj = {};
options_params = []; options_params = [];
resolved = "" resolved = ""
// proceed only if first option item contains something to resolve // proceed only if first option item contains something to resolve
if( !set.setKey.includes("__metadata") && if( !set.setKey.includes("__metadata") &&
resolvedOptions.length != 0 && resolvedOptions.length != 0 &&
resolvedOptions[0].includes("{value}")) resolvedOptions[0].includes("{value}"))
{ {
// get setting definition from the plugin config if available // get setting definition from the plugin config if available
setPlugObj = getPluginSettingObject(pluginsData, set.setKey) setPlugObj = getPluginSettingObject(pluginsData, set.setKey)
// check if options contains parameters and resolve // check if options contains parameters and resolve
if(setPlugObj != {} && setPlugObj["options_params"]) if(setPlugObj != {} && setPlugObj["options_params"])
{ {
// get option_params for {value} resolution // get option_params for {value} resolution
options_params = setPlugObj["options_params"] options_params = setPlugObj["options_params"]
if(options_params != []) if(options_params != [])
{ {
@@ -154,19 +154,19 @@ function cacheSettings()
{ {
resolvedOptions = `[${resolved}]` resolvedOptions = `[${resolved}]`
} else // one value only } else // one value only
{ {
resolvedOptions = `["${resolved}"]` resolvedOptions = `["${resolved}"]`
} }
} }
} }
} }
setCache(`nax_set_${set.setKey}`, set.setValue) setCache(`nax_set_${set.setKey}`, set.setValue)
setCache(`nax_set_opt_${set.setKey}`, resolvedOptions) setCache(`nax_set_opt_${set.setKey}`, resolvedOptions)
}); });
}).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization }).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization
}) })
} }
}); });
} }
@@ -176,7 +176,7 @@ function getSettingOptions (key) {
// handle initial load to make sure everything is set-up and cached // handle initial load to make sure everything is set-up and cached
// handleFirstLoad() // handleFirstLoad()
result = getCache(`nax_set_opt_${key}`, true); result = getCache(`nax_set_opt_${key}`, true);
if (result == "") if (result == "")
@@ -194,7 +194,7 @@ function getSetting (key) {
// handle initial load to make sure everything is set-up and cached // handle initial load to make sure everything is set-up and cached
// handleFirstLoad() // handleFirstLoad()
result = getCache(`nax_set_${key}`, true); result = getCache(`nax_set_${key}`, true);
if (result == "") if (result == "")
@@ -210,7 +210,7 @@ function getSetting (key) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function cacheStrings() { function cacheStrings() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Create a promise for each language (include en_us by default as fallback) // Create a promise for each language (include en_us by default as fallback)
languagesToLoad = ['en_us'] languagesToLoad = ['en_us']
@@ -222,11 +222,11 @@ function cacheStrings() {
} }
console.log(languagesToLoad); console.log(languagesToLoad);
const languagePromises = languagesToLoad.map((language_code) => { const languagePromises = languagesToLoad.map((language_code) => {
return new Promise((resolveLang, rejectLang) => { return new Promise((resolveLang, rejectLang) => {
// Fetch core strings and translations // Fetch core strings and translations
$.get(`php/templates/language/${language_code}.json?nocache=${Date.now()}`) $.get(`php/templates/language/${language_code}.json?nocache=${Date.now()}`)
.done((res) => { .done((res) => {
// Iterate over each key-value pair and store the translations // Iterate over each key-value pair and store the translations
@@ -238,7 +238,7 @@ function cacheStrings() {
$.get('php/server/query_json.php', { file: 'table_plugins_language_strings.json', nocache: Date.now() }) $.get('php/server/query_json.php', { file: 'table_plugins_language_strings.json', nocache: Date.now() })
.done((pluginRes) => { .done((pluginRes) => {
const data = pluginRes["data"]; const data = pluginRes["data"];
// Store plugin translations // Store plugin translations
data.forEach((langString) => { data.forEach((langString) => {
setCache(`pia_lang_${langString.String_Key}_${langString.Language_Code}`, langString.String_Value); setCache(`pia_lang_${langString.String_Key}_${langString.Language_Code}`, langString.String_Value);
@@ -269,7 +269,7 @@ function cacheStrings() {
// Handle failure in any of the language processing // Handle failure in any of the language processing
handleFailure('cacheStrings', reject); handleFailure('cacheStrings', reject);
}); });
}); });
} }
@@ -278,7 +278,7 @@ function cacheStrings() {
function getString(key) { function getString(key) {
function fetchString(key) { function fetchString(key) {
lang_code = getLangCode(); lang_code = getLangCode();
let result = getCache(`pia_lang_${key}_${lang_code}`, true); let result = getCache(`pia_lang_${key}_${lang_code}`, true);
@@ -509,7 +509,7 @@ function isBase64(value) {
const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/; const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/;
if (!base64Regex.test(value)) return false; if (!base64Regex.test(value)) return false;
try { try {
const decoded = atob(value); const decoded = atob(value);
@@ -568,7 +568,7 @@ function decodeSpecialChars(str) {
function utf8ToBase64(str) { function utf8ToBase64(str) {
// Convert the string to a Uint8Array using TextEncoder // Convert the string to a Uint8Array using TextEncoder
const utf8Bytes = new TextEncoder().encode(str); const utf8Bytes = new TextEncoder().encode(str);
// Convert the Uint8Array to a base64-encoded string // Convert the Uint8Array to a base64-encoded string
return btoa(String.fromCharCode(...utf8Bytes)); return btoa(String.fromCharCode(...utf8Bytes));
} }
@@ -597,31 +597,31 @@ function handle_locked_DB(data)
{ {
if(data.includes('database is locked')) if(data.includes('database is locked'))
{ {
// console.log(data) // console.log(data)
showSpinner() showSpinner()
setTimeout(function() { setTimeout(function() {
console.warn("Database locked - reload") console.warn("Database locked - reload")
location.reload(); location.reload();
}, 5000); }, 5000);
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function numberArrayFromString(data) function numberArrayFromString(data)
{ {
data = JSON.parse(sanitize(data)); data = JSON.parse(sanitize(data));
return data.replace(/\[|\]/g, '').split(',').map(Number); return data.replace(/\[|\]/g, '').split(',').map(Number);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function saveData(functionName, id, value) { function saveData(functionName, id, value) {
$.ajax({ $.ajax({
method: "GET", method: "GET",
url: "php/server/devices.php", url: "php/server/devices.php",
data: { action: functionName, id: id, value:value }, data: { action: functionName, id: id, value:value },
success: function(data) { success: function(data) {
if(sanitize(data) == 'OK') if(sanitize(data) == 'OK')
{ {
showMessage("Saved") showMessage("Saved")
@@ -630,7 +630,7 @@ function saveData(functionName, id, value) {
} else } else
{ {
showMessage("ERROR") showMessage("ERROR")
} }
} }
}); });
@@ -670,13 +670,13 @@ function sleep(milliseconds) {
} while (currentDate - date < milliseconds); } while (currentDate - date < milliseconds);
} }
// --------------------------------------------------------- // ---------------------------------------------------------
somethingChanged = false; somethingChanged = false;
function settingsChanged() function settingsChanged()
{ {
somethingChanged = true; somethingChanged = true;
// Enable navigation prompt ... "Are you sure you want to leave..." // Enable navigation prompt ... "Are you sure you want to leave..."
window.onbeforeunload = function() { window.onbeforeunload = function() {
return true; return true;
}; };
} }
@@ -694,16 +694,16 @@ function getUrlAnchor(defaultValue){
selectedTab = defaultValue selectedTab = defaultValue
// the #target from the url // the #target from the url
target = window.location.hash.substr(1) target = window.location.hash.substr(1)
// get only the part between #...? // get only the part between #...?
if(target.includes('?')) if(target.includes('?'))
{ {
target = target.split('?')[0] target = target.split('?')[0]
} }
return target return target
} }
} }
@@ -715,7 +715,7 @@ function getQueryString(key){
get: (searchParams, prop) => searchParams.get(prop), get: (searchParams, prop) => searchParams.get(prop),
}); });
tmp = params[key] tmp = params[key]
if(emptyArr.includes(tmp)) if(emptyArr.includes(tmp))
{ {
@@ -726,17 +726,17 @@ function getQueryString(key){
if (fullUrl.includes('?')) { if (fullUrl.includes('?')) {
var queryString = fullUrl.split('?')[1]; var queryString = fullUrl.split('?')[1];
// Split the query string into individual parameters // Split the query string into individual parameters
var paramsArray = queryString.split('&'); var paramsArray = queryString.split('&');
// Loop through the parameters array // Loop through the parameters array
paramsArray.forEach(function(param) { paramsArray.forEach(function(param) {
// Split each parameter into key and value // Split each parameter into key and value
var keyValue = param.split('='); var keyValue = param.split('=');
var keyTmp = decodeURIComponent(keyValue[0]); var keyTmp = decodeURIComponent(keyValue[0]);
var value = decodeURIComponent(keyValue[1] || ''); var value = decodeURIComponent(keyValue[1] || '');
// Store key-value pair in the queryParams object // Store key-value pair in the queryParams object
queryParams[keyTmp] = value; queryParams[keyTmp] = value;
}); });
@@ -750,7 +750,7 @@ function getQueryString(key){
result = emptyArr.includes(tmp) ? "" : tmp; result = emptyArr.includes(tmp) ? "" : tmp;
return result return result
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function translateHTMLcodes (text) { function translateHTMLcodes (text) {
if (text == null || emptyArr.includes(text)) { if (text == null || emptyArr.includes(text)) {
@@ -769,14 +769,14 @@ function translateHTMLcodes (text) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function stopTimerRefreshData () { function stopTimerRefreshData () {
try { try {
clearTimeout (timerRefreshData); clearTimeout (timerRefreshData);
} catch (e) {} } catch (e) {}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function newTimerRefreshData (refeshFunction, timeToRefresh) { function newTimerRefreshData (refeshFunction, timeToRefresh) {
if(timeToRefresh && (timeToRefresh != 0 || timeToRefresh != "")) if(timeToRefresh && (timeToRefresh != 0 || timeToRefresh != ""))
{ {
time = parseInt(timeToRefresh) time = parseInt(timeToRefresh)
@@ -813,7 +813,7 @@ function openInNewTab (url) {
window.open(url, "_blank"); window.open(url, "_blank");
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Navigate to URL if the current URL is not in the provided list of URLs // Navigate to URL if the current URL is not in the provided list of URLs
function openUrl(urls) { function openUrl(urls) {
var currentUrl = window.location.href; var currentUrl = window.location.href;
@@ -844,21 +844,21 @@ function openUrl(urls) {
function forceLoadUrl(relativeUrl) { function forceLoadUrl(relativeUrl) {
window.location.replace(relativeUrl); window.location.replace(relativeUrl);
window.location.reload() window.location.reload()
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function navigateToDeviceWithIp (ip) { function navigateToDeviceWithIp (ip) {
$.get('php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(res) { $.get('php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(res) {
devices = res["data"]; devices = res["data"];
mac = "" mac = ""
$.each(devices, function(index, obj) { $.each(devices, function(index, obj) {
if(obj.devLastIP.trim() == ip.trim()) if(obj.devLastIP.trim() == ip.trim())
{ {
mac = obj.devMac; mac = obj.devMac;
@@ -866,7 +866,7 @@ function navigateToDeviceWithIp (ip) {
window.open('./deviceDetails.php?mac=' + mac , "_blank"); window.open('./deviceDetails.php?mac=' + mac , "_blank");
} }
}); });
}); });
} }
@@ -898,7 +898,7 @@ function getMac(){
}); });
return params.mac return params.mac
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// A function used to make the IP address orderable // A function used to make the IP address orderable
@@ -950,7 +950,7 @@ function isRandomMAC(mac)
{ {
isRandom = false; isRandom = false;
isRandom = ["2", "6", "A", "E", "a", "e"].includes(mac[1]); isRandom = ["2", "6", "A", "E", "a", "e"].includes(mac[1]);
// if detected as random, make sure it doesn't start with a prefix which teh suer doesn't want to mark as random // if detected as random, make sure it doesn't start with a prefix which teh suer doesn't want to mark as random
if(isRandom) if(isRandom)
@@ -959,17 +959,17 @@ function isRandomMAC(mac)
if(mac.startsWith(prefix)) if(mac.startsWith(prefix))
{ {
isRandom = false; isRandom = false;
} }
}); });
} }
return isRandom; return isRandom;
} }
// --------------------------------------------------------- // ---------------------------------------------------------
// Generate an array object from a string representation of an array // Generate an array object from a string representation of an array
function createArray(input) { function createArray(input) {
// Is already array, return // Is already array, return
@@ -980,25 +980,25 @@ function isRandomMAC(mac)
if (input === '[]' || input === '') { if (input === '[]' || input === '') {
return []; return [];
} }
// handle integer // handle integer
if (typeof input === 'number') { if (typeof input === 'number') {
input = input.toString(); input = input.toString();
} }
// Regex pattern for brackets // Regex pattern for brackets
const patternBrackets = /(^\s*\[)|(\]\s*$)/g; const patternBrackets = /(^\s*\[)|(\]\s*$)/g;
const replacement = ''; const replacement = '';
// Remove brackets // Remove brackets
const noBrackets = input.replace(patternBrackets, replacement); const noBrackets = input.replace(patternBrackets, replacement);
const options = []; const options = [];
// Detect the type of quote used after the opening bracket // Detect the type of quote used after the opening bracket
const firstChar = noBrackets.trim()[0]; const firstChar = noBrackets.trim()[0];
const isDoubleQuoted = firstChar === '"'; const isDoubleQuoted = firstChar === '"';
const isSingleQuoted = firstChar === "'"; const isSingleQuoted = firstChar === "'";
// Create array while handling commas within quoted segments // Create array while handling commas within quoted segments
let currentSegment = ''; let currentSegment = '';
let withinQuotes = false; let withinQuotes = false;
@@ -1016,7 +1016,7 @@ function isRandomMAC(mac)
} }
// Push the last segment // Push the last segment
options.push(currentSegment.trim()); options.push(currentSegment.trim());
// Remove quotes based on detected type // Remove quotes based on detected type
options.forEach((item, index) => { options.forEach((item, index) => {
let trimmedItem = item.trim(); let trimmedItem = item.trim();
@@ -1028,7 +1028,7 @@ function isRandomMAC(mac)
} }
options[index] = trimmedItem; options[index] = trimmedItem;
}); });
return options; return options;
} }
@@ -1037,7 +1037,7 @@ function isRandomMAC(mac)
// for the value to be returned // for the value to be returned
function getDevDataByMac(macAddress, dbColumn) { function getDevDataByMac(macAddress, dbColumn) {
const sessionDataKey = 'devicesListAll_JSON'; const sessionDataKey = 'devicesListAll_JSON';
const devicesCache = getCache(sessionDataKey); const devicesCache = getCache(sessionDataKey);
if (!devicesCache || devicesCache == "") { if (!devicesCache || devicesCache == "") {
@@ -1068,11 +1068,11 @@ function getDevDataByMac(macAddress, dbColumn) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Cache the devices as one JSON // Cache the devices as one JSON
function cacheDevices() function cacheDevices()
{ {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$.get('php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(data) { $.get('php/server/query_json.php', { file: 'table_devices.json', nocache: Date.now() }, function(data) {
// console.log(data) // console.log(data)
devicesListAll_JSON = data["data"] devicesListAll_JSON = data["data"]
@@ -1093,11 +1093,11 @@ function cacheDevices()
// console.log(getCache('devicesListAll_JSON')) // console.log(getCache('devicesListAll_JSON'))
}).then(() => handleSuccess('cacheDevices', resolve())).catch(() => handleFailure('cacheDevices', reject("cacheDevices already completed"))); // handle AJAX synchronization }).then(() => handleSuccess('cacheDevices', resolve())).catch(() => handleFailure('cacheDevices', reject("cacheDevices already completed"))); // handle AJAX synchronization
} }
); );
} }
var devicesListAll_JSON = []; // this will contain a list off all devices var devicesListAll_JSON = []; // this will contain a list off all devices
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function isEmpty(value) function isEmpty(value)
@@ -1127,7 +1127,7 @@ function getGuid() {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// UI // UI
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -1230,7 +1230,7 @@ function hideSpinner() {
}); });
} }
// -------------------------------------------------------- // --------------------------------------------------------
// 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
function updateApi(apiEndpoints) function updateApi(apiEndpoints)
@@ -1250,9 +1250,9 @@ function updateApi(apiEndpoints)
}) })
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// handling smooth scrolling // handling smooth scrolling
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function setupSmoothScrolling() { function setupSmoothScrolling() {
// Function to scroll to the element // Function to scroll to the element
function scrollToElement(id) { function scrollToElement(id) {
@@ -1310,17 +1310,17 @@ function getPluginSettingObject(pluginsData, setting_key, unique_prefix ) {
result = {} result = {}
unique_prefix == undefined ? unique_prefix = setting_key.split("_")[0] : unique_prefix = unique_prefix; unique_prefix == undefined ? unique_prefix = setting_key.split("_")[0] : unique_prefix = unique_prefix;
$.each(pluginsData, function (i, plgnObj){ $.each(pluginsData, function (i, plgnObj){
// go thru plugins // go thru plugins
if(plgnObj.unique_prefix == unique_prefix) if(plgnObj.unique_prefix == unique_prefix)
{ {
// go thru plugin settings // go thru plugin settings
$.each(plgnObj["settings"], function (j, setObj){ $.each(plgnObj["settings"], function (j, setObj){
if(`${unique_prefix}_${setObj.function}` == setting_key) if(`${unique_prefix}_${setObj.function}` == setting_key)
{ {
result = setObj result = setObj
} }
}); });
@@ -1372,7 +1372,7 @@ function arraysContainSameValues(arr1, arr2) {
if (!Array.isArray(arr1) || !Array.isArray(arr2)) { if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
return false; return false;
} else } else
{ {
// Sort and stringify arrays, then compare // Sort and stringify arrays, then compare
return JSON.stringify(arr1.slice().sort()) === JSON.stringify(arr2.slice().sort()); return JSON.stringify(arr1.slice().sort()) === JSON.stringify(arr2.slice().sort());
} }
@@ -1383,7 +1383,7 @@ function arraysContainSameValues(arr1, arr2) {
function hideUIelements(setKey) { function hideUIelements(setKey) {
hiddenSectionsSetting = getSetting(setKey) hiddenSectionsSetting = getSetting(setKey)
if(hiddenSectionsSetting != "") // handle if settings not yet initialized if(hiddenSectionsSetting != "") // handle if settings not yet initialized
{ {
@@ -1398,9 +1398,9 @@ function hideUIelements(setKey) {
if($('#' + hiddenSection)) if($('#' + hiddenSection))
{ {
$('#' + hiddenSection).hide() $('#' + hiddenSection).hide()
} }
}); });
} }
@@ -1411,7 +1411,7 @@ function getDevicesList()
{ {
// Read cache (skip cookie expiry check) // Read cache (skip cookie expiry check)
devicesList = getCache('devicesListAll_JSON', true); devicesList = getCache('devicesListAll_JSON', true);
if (devicesList != '') { if (devicesList != '') {
devicesList = JSON.parse (devicesList); devicesList = JSON.parse (devicesList);
} else { } else {
@@ -1468,7 +1468,7 @@ $(document).ready(function() {
// Restart Backend Python Server // Restart Backend Python Server
function askRestartBackend() { function askRestartBackend() {
// Ask // Ask
showModalWarning(getString('Maint_RestartServer'), getString('Maint_Restart_Server_noti_text'), showModalWarning(getString('Maint_RestartServer'), getString('Maint_Restart_Server_noti_text'),
getString('Gen_Cancel'), getString('Maint_RestartServer'), 'restartBackend'); getString('Gen_Cancel'), getString('Maint_RestartServer'), 'restartBackend');
} }
@@ -1477,7 +1477,7 @@ function askRestartBackend() {
function restartBackend() { function restartBackend() {
modalEventStatusId = 'modal-message-front-event' modalEventStatusId = 'modal-message-front-event'
// Execute // Execute
$.ajax({ $.ajax({
method: "POST", method: "POST",
@@ -1523,7 +1523,7 @@ function clearCache() {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Function to check if cache needs to be refreshed because of setting changes // Function to check if cache needs to be refreshed because of setting changes
function checkSettingChanges() { function checkSettingChanges() {
$.get('php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) { $.get('php/server/query_json.php', { file: 'app_state.json', nocache: Date.now() }, function(appState) {
const importedMilliseconds = parseInt(appState["settingsImported"] * 1000); const importedMilliseconds = parseInt(appState["settingsImported"] * 1000);
const lastReloaded = parseInt(sessionStorage.getItem(sessionStorageKey + '_time')); const lastReloaded = parseInt(sessionStorage.getItem(sessionStorageKey + '_time'));
@@ -1594,7 +1594,7 @@ function isAppInitialized() {
lang_shouldBeCompletedCalls = getLangCode() == 'en_us' ? 1 : 2; lang_shouldBeCompletedCalls = getLangCode() == 'en_us' ? 1 : 2;
// check if each ajax call completed succesfully // check if each ajax call completed succesfully
$.each(completedCalls_final, function(index, call_name){ $.each(completedCalls_final, function(index, call_name){
if(getCache(call_name + "_completed") != "true") if(getCache(call_name + "_completed") != "true")
@@ -1622,8 +1622,7 @@ async function executeOnce() {
if (!isAppInitialized()) { if (!isAppInitialized()) {
try { try {
console.log("HERE");
await waitForGraphQLServer(); // Wait for the server to start await waitForGraphQLServer(); // Wait for the server to start
await cacheDevices(); await cacheDevices();
@@ -1680,7 +1679,7 @@ const onAllCallsComplete = () => {
// setTimeout(() => { // setTimeout(() => {
// location.reload() // location.reload()
// }, 10); // }, 10);
} else { } else {
// If not all strings are initialized, retry initialization // If not all strings are initialized, retry initialization
console.log('❌ Not all strings are initialized. Retrying...'); console.log('❌ Not all strings are initialized. Retrying...');
@@ -1702,7 +1701,7 @@ const areAllStringsInitialized = () => {
// Call the function to execute the code // Call the function to execute the code
executeOnce(); executeOnce();
// Set timer for regular UI refresh if enabled // Set timer for regular UI refresh if enabled
setTimeout(() => { setTimeout(() => {
// page refresh if configured // page refresh if configured