diff --git a/front/devices.php b/front/devices.php
index 44a8680c..5c780ca8 100755
--- a/front/devices.php
+++ b/front/devices.php
@@ -159,6 +159,7 @@
var tableColumnHide = [];
var tableColumnOrder = [];
var tableColumnVisible = [];
+ headersDefaultOrder = [];
// Read parameters & Initialize components
callAfterAppInitialized(main)
@@ -171,7 +172,7 @@ function main () {
//initialize the table headers in the correct order
var availableColumns = getSettingOptions("UI_device_columns").split(",");
- var headersDefaultOrder = availableColumns.map(val => getString(val));
+ headersDefaultOrder = availableColumns.map(val => getString(val));
var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
// generate default order lists of given length
@@ -197,18 +198,6 @@ function main () {
// Concatenate the inputArray with the missingNumbers
tableColumnOrder = [...tableColumnVisible, ...missingNumbers];
- // render table headers
- html = '';
-
- for(index = 0; index < tableColumnOrder.length; index++)
- {
- html += '
' + headersDefaultOrder[tableColumnOrder[index]] + ' ';
- }
-
- $('#tableDevices tr').html(html);
-
- hideUIelements("UI_DEV_SECTIONS")
-
// Initialize components with parameters
initializeDatatable(getUrlAnchor('my_devices'));
@@ -376,12 +365,13 @@ function getDeviceStatus(item)
}
// -----------------------------------------------------------------------------
-function initializeDatatable_new (status) {
+function initializeDatatable_n (status) {
- console.log(tableColumnVisible);
+console.log(tableColumnVisible);
// Build GraphQL query dynamically based on tableColumnVisible
+let requiredColumns = ['devMac', 'devName', 'devIsNew', 'devPresentLastScan', 'devAlertDown', 'devIsArchived']
let columnsToFetch = [
'devMac', 'devName', 'devLastConnection', 'devIsArchived', 'devOwner', 'devType',
'devIcon', 'devFavorite', 'devGroup', 'devFirstConnection', 'devLastIP', 'devNetworkNodeMAC',
@@ -391,6 +381,8 @@ let columnsToFetch = [
let selectedColumns = columnsToFetch.filter(col => tableColumnVisible.includes(col));
+
+
// Construct the GraphQL query
let graphqlQuery = `
query {
@@ -536,9 +528,10 @@ $.ajax({
}
-
+// ---------------------------------------------------------
function initializeDatatable (status) {
+
if(!status)
{
status = 'my_devices'
@@ -565,6 +558,17 @@ function initializeDatatable (status) {
$('#tableDevicesBox')[0].className = 'box box-'+ color;
$('#tableDevicesTitle').html (tableTitle);
+ // render table headers
+ html = '';
+
+ for(index = 0; index < tableColumnOrder.length; index++)
+ {
+ html += '' + headersDefaultOrder[tableColumnOrder[index]] + ' ';
+ }
+
+ $('#tableDevices tr').html(html);
+
+ hideUIelements("UI_DEV_SECTIONS")
for(i = 0; i < tableColumnOrder.length; i++)
{
@@ -575,268 +579,322 @@ function initializeDatatable (status) {
}
}
- $.get('api/table_devices.json?nocache=' + Date.now(), function(result) {
-
- // refresh devices cache
- devicesListAll_JSON = result["data"]
- devicesListAll_JSON_str = JSON.stringify(devicesListAll_JSON)
- setCache('devicesListAll_JSON', devicesListAll_JSON_str)
-
- // query data
- getDevicesTotals(result.data);
-
- // Filter the data based on deviceStatus
- var filteredData = filterDataByStatus(result.data, deviceStatus);
-
- // Convert JSON data into the desired format
- var dataArray = {
- data: filteredData.map(function(item) {
- var originalRow = [
- item.devName || "",
- item.devOwner || "",
- item.devType || "",
- item.devIcon || "",
- item.devFavorite || "",
- item.devGroup || "",
- // ---
- item.devFirstConnection || "",
- item.devLastConnection || "",
- item.devLastIP || "",
- (isRandomMAC(item.devMac)) || "", // Check if randomized MAC
- getDeviceStatus(item) || "",
- item.devMac || "", // hidden
- formatIPlong(item.devLastIP) || "", // IP orderable
- item.rowid || "",
- item.devParentMAC || "",
- getNumberOfChildren(item.devMac, result.data) || 0,
- item.devLocation || "",
- item.devVendor || "",
- item.devParentPort || 0,
- item.devGUID || "",
- item.devSyncHubNode || "",
- item.devSite || "",
- item.devSSID || "",
- item.devSourcePlugin || ""
- ];
-
- var newRow = [];
-
- // reorder data based on user-defined columns order
- for (index = 0; index < tableColumnOrder.length; index++) {
- newRow.push(originalRow[tableColumnOrder[index]]);
- }
-
- return newRow;
- })
- };
-
- // Check if the DataTable already exists
- if ($.fn.dataTable.isDataTable('#tableDevices')) {
- // The DataTable exists, so destroy it
- var table = $('#tableDevices').DataTable();
- table.clear().destroy();
- }
-
- var table =
- $('#tableDevices').DataTable({
- 'data' : dataArray["data"],
- 'paging' : true,
- 'lengthChange' : true,
- 'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
- 'searching' : true,
-
- 'ordering' : true,
- 'info' : true,
- 'autoWidth' : false,
-
- // Parameters
- 'pageLength' : tableRows,
- 'order' : tableOrder,
- 'select' : true, // Enable selection
-
- 'columnDefs' : [
- {visible: false, targets: tableColumnHide },
- {className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] },
- {width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15)] },
- {width: '30px', targets: [mapIndx(10), mapIndx(13), mapIndx(18)] },
- {orderData: [mapIndx(12)], targets: mapIndx(8) },
-
- // Device Name
- {targets: [mapIndx(0)],
- 'createdCell': function (td, cellData, rowData, row, col) {
-
- // console.log(cellData)
- $(td).html (''+ cellData +' ');
- } },
-
- // Connected Devices
- {targets: [mapIndx(15)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- // check if this is a network device
- if(getSetting("NETWORK_DEVICE_TYPES").includes(`'${rowData[mapIndx(2)]}'`) )
- {
- $(td).html (''+ cellData +' ');
- }
- else
- {
- $(td).html (` `)
- }
-
- } },
-
- // Icon
- {targets: [mapIndx(3)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- if (!emptyArr.includes(cellData)){
- $(td).html (atob(cellData));
- } else {
- $(td).html ('');
- }
- } },
-
- // Full MAC
- {targets: [mapIndx(11)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- if (!emptyArr.includes(cellData)){
- $(td).html (''+cellData+' ');
- } else {
- $(td).html ('');
- }
- } },
-
- // IP address
- {targets: [mapIndx(8)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- if (!emptyArr.includes(cellData)){
- $(td).html (`
-
- ${cellData}
-
-
-
-
- `);
- } else {
- $(td).html ('');
- }
- }
- },
- // IP address (ordeable)
- {targets: [mapIndx(12)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- if (!emptyArr.includes(cellData)){
- $(td).html (`${cellData}`);
- } else {
- $(td).html ('');
- }
- }
- },
-
- // Favorite
- {targets: [mapIndx(4)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- if (cellData == 1){
- $(td).html (' ');
- } else {
- $(td).html ('');
- }
- } },
-
- // Dates
- {targets: [mapIndx(6), mapIndx(7)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- var result = cellData.toString(); // Convert to string
- if (result.includes("+")) { // Check if timezone offset is present
- result = result.split('+')[0]; // Remove timezone offset
- }
- $(td).html (translateHTMLcodes (result));
- } },
-
- // Random MAC
- {targets: [mapIndx(9)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- // console.log(cellData)
- if (cellData == 1){
- $(td).html (' ');
- } else {
- $(td).html ('');
- }
- } },
-
- // Status color
- {targets: [mapIndx(10)],
- 'createdCell': function (td, cellData, rowData, row, col) {
-
- devData = getDeviceDataByMac(rowData[mapIndx(11)])
-
- if (devData.devPresentLastScan == 1)
- {
- css = "green text-white statusOnline"
- icon = ' '
- } else if (devData.devPresentLastScan != 1 && devData.devAlertDown == 1)
- {
- css = "red text-white statusDown"
- icon = ' '
- } else if(devData.devPresentLastScan != 1)
- {
- css = "gray text-white statusOffline"
- icon = ' '
- } else
- {
- css = "gray text-white statusUnknown"
- icon = ' '
- }
-
- $(td).html (`${icon} ${cellData.replace('-', '')} `);
- } },
- ],
-
- // Processing
- 'processing' : true,
- 'language' : {
- processing: '',
- emptyTable: 'No data',
- "lengthMenu": "= lang('Device_Tablelenght');?>",
- "search": "= lang('Device_Searchbox');?>: ",
- "paginate": {
- "next": "= lang('Device_Table_nav_next');?>",
- "previous": "= lang('Device_Table_nav_prev');?>"
- },
- "info": "= lang('Device_Table_info');?>",
+ // Construct the GraphQL query
+ let graphqlQuery = `
+ query {
+ devices {
+ rowid
+ devMac
+ devName
+ devOwner
+ devType
+ devVendor
+ devFavorite
+ devGroup
+ devComments
+ devFirstConnection
+ devLastConnection
+ devLastIP
+ devStaticIP
+ devScan
+ devLogEvents
+ devAlertEvents
+ devAlertDown
+ devSkipRepeated
+ devLastNotification
+ devPresentLastScan
+ devIsNew
+ devLocation
+ devIsArchived
+ devParentMAC
+ devParentPort
+ devIcon
+ devGUID
+ devSite
+ devSSID
+ devSyncHubNode
+ devSourcePlugin
+ }
}
- });
+ `;
- // Save cookie Rows displayed, and Parameters rows & order
- $('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
- setCookie ("nax_parTableRows", len, 129600); // save for 90 days
- } );
+ console.log(graphqlQuery);
+
+
+ $.ajax({
+ url: 'php/server/query_graphql.php', // PHP endpoint that proxies to the GraphQL server
+ type: 'POST',
+ contentType: 'application/json',
+ data: JSON.stringify({
+ query: graphqlQuery,
+ variables: {} // Optional: pass variables if needed
+ }),
+ success: function(result) {
+
+ // refresh devices cache
+ devicesListAll_JSON = result["devices"];
+ console.log(devicesListAll_JSON);
- $('#tableDevices').on( 'order.dt', function () {
- setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
- } );
-
- // add multi-edit button
- $('#multiEditPlc').append(
- `
- ${getString("Device_MultiEdit")}
- `)
-
- // Event listener for row selection in DataTable
- $('#tableDevices').on('click', 'tr', function (e) {
- setTimeout(function(){
- // Check if any row is selected
- var anyRowSelected = $('#tableDevices tr.selected').length > 0;
-
- // Toggle visibility of element with ID 'multiEdit'
- $('#multiEdit').toggle(anyRowSelected);
- }, 200);
-
+ devicesListAll_JSON_str = JSON.stringify(devicesListAll_JSON)
+ setCache('devicesListAll_JSON', devicesListAll_JSON_str)
- });
+ // query data
+ getDevicesTotals(result.devices);
+
+ // Filter the data based on deviceStatus
+ var filteredData = filterDataByStatus(result.devices, deviceStatus);
- hideSpinner();
+ // Convert JSON data into the desired format
+ var dataArray = {
+ data: filteredData.map(function(item) {
+ var originalRow = [
+ item.devName || "",
+ item.devOwner || "",
+ item.devType || "",
+ item.devIcon || "",
+ item.devFavorite || "",
+ item.devGroup || "",
+ item.devFirstConnection || "",
+ item.devLastConnection || "",
+ item.devLastIP || "",
+ (isRandomMAC(item.devMac)) || "", // Check if randomized MAC
+ getDeviceStatus(item) || "",
+ item.devMac || "", // hidden
+ formatIPlong(item.devLastIP) || "", // IP orderable
+ item.rowid || "",
+ item.devParentMAC || "",
+ getNumberOfChildren(item.devMac, result.devices) || 0,
+ item.devLocation || "",
+ item.devVendor || "",
+ item.devParentPort || 0,
+ item.devGUID || "",
+ item.devSyncHubNode || "",
+ item.devSite || "",
+ item.devSSID || "",
+ item.devSourcePlugin || ""
+ ];
- });
+ var newRow = [];
+
+ // reorder data based on user-defined columns order
+ for (index = 0; index < tableColumnOrder.length; index++) {
+ newRow.push(originalRow[tableColumnOrder[index]]);
+ }
+
+ return newRow;
+ })
+ };
+
+ // Check if the DataTable already exists
+ if ($.fn.dataTable.isDataTable('#tableDevices')) {
+ // The DataTable exists, so destroy it
+ var table = $('#tableDevices').DataTable();
+ table.clear().destroy();
+ }
+
+ var table =
+ $('#tableDevices').DataTable({
+ 'data' : dataArray["data"],
+ 'paging' : true,
+ 'lengthChange' : true,
+ 'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
+ 'searching' : true,
+
+ 'ordering' : true,
+ 'info' : true,
+ 'autoWidth' : false,
+
+ // Parameters
+ 'pageLength' : tableRows,
+ 'order' : tableOrder,
+ 'select' : true, // Enable selection
+
+ 'columnDefs' : [
+ {visible: false, targets: tableColumnHide },
+ {className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] },
+ {width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15)] },
+ {width: '30px', targets: [mapIndx(10), mapIndx(13), mapIndx(18)] },
+ {orderData: [mapIndx(12)], targets: mapIndx(8) },
+
+ // Device Name
+ {targets: [mapIndx(0)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+
+ // console.log(cellData)
+ $(td).html (''+ cellData +' ');
+ } },
+
+ // Connected Devices
+ {targets: [mapIndx(15)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ // check if this is a network device
+ if(getSetting("NETWORK_DEVICE_TYPES").includes(`'${rowData[mapIndx(2)]}'`) )
+ {
+ $(td).html (''+ cellData +' ');
+ }
+ else
+ {
+ $(td).html (` `)
+ }
+
+ } },
+
+ // Icon
+ {targets: [mapIndx(3)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ if (!emptyArr.includes(cellData)){
+ $(td).html (atob(cellData));
+ } else {
+ $(td).html ('');
+ }
+ } },
+
+ // Full MAC
+ {targets: [mapIndx(11)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ if (!emptyArr.includes(cellData)){
+ $(td).html (''+cellData+' ');
+ } else {
+ $(td).html ('');
+ }
+ } },
+
+ // IP address
+ {targets: [mapIndx(8)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ if (!emptyArr.includes(cellData)){
+ $(td).html (`
+
+ ${cellData}
+
+
+
+
+ `);
+ } else {
+ $(td).html ('');
+ }
+ }
+ },
+ // IP address (ordeable)
+ {targets: [mapIndx(12)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ if (!emptyArr.includes(cellData)){
+ $(td).html (`${cellData}`);
+ } else {
+ $(td).html ('');
+ }
+ }
+ },
+
+ // Favorite
+ {targets: [mapIndx(4)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ if (cellData == 1){
+ $(td).html (' ');
+ } else {
+ $(td).html ('');
+ }
+ } },
+
+ // Dates
+ {targets: [mapIndx(6), mapIndx(7)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ var result = cellData.toString(); // Convert to string
+ if (result.includes("+")) { // Check if timezone offset is present
+ result = result.split('+')[0]; // Remove timezone offset
+ }
+ $(td).html (translateHTMLcodes (result));
+ } },
+
+ // Random MAC
+ {targets: [mapIndx(9)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+ // console.log(cellData)
+ if (cellData == 1){
+ $(td).html (' ');
+ } else {
+ $(td).html ('');
+ }
+ } },
+
+ // Status color
+ {targets: [mapIndx(10)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+
+ devData = getDeviceDataByMac(rowData[mapIndx(11)])
+
+ if (devData.devPresentLastScan == 1)
+ {
+ css = "green text-white statusOnline"
+ icon = ' '
+ } else if (devData.devPresentLastScan != 1 && devData.devAlertDown == 1)
+ {
+ css = "red text-white statusDown"
+ icon = ' '
+ } else if(devData.devPresentLastScan != 1)
+ {
+ css = "gray text-white statusOffline"
+ icon = ' '
+ } else
+ {
+ css = "gray text-white statusUnknown"
+ icon = ' '
+ }
+
+ $(td).html (`${icon} ${cellData.replace('-', '')} `);
+ } },
+ ],
+
+ // Processing
+ 'processing' : true,
+ 'language' : {
+ processing: '',
+ emptyTable: 'No data',
+ "lengthMenu": "= lang('Device_Tablelenght');?>",
+ "search": "= lang('Device_Searchbox');?>: ",
+ "paginate": {
+ "next": "= lang('Device_Table_nav_next');?>",
+ "previous": "= lang('Device_Table_nav_prev');?>"
+ },
+ "info": "= lang('Device_Table_info');?>",
+ }
+ });
+
+ // Save cookie Rows displayed, and Parameters rows & order
+ $('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
+ setCookie ("nax_parTableRows", len, 129600); // save for 90 days
+ } );
+
+ $('#tableDevices').on( 'order.dt', function () {
+ setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
+ } );
+
+ // add multi-edit button
+ $('#multiEditPlc').append(
+ `
+ ${getString("Device_MultiEdit")}
+ `)
+
+ // Event listener for row selection in DataTable
+ $('#tableDevices').on('click', 'tr', function (e) {
+ setTimeout(function(){
+ // Check if any row is selected
+ var anyRowSelected = $('#tableDevices tr.selected').length > 0;
+
+ // Toggle visibility of element with ID 'multiEdit'
+ $('#multiEdit').toggle(anyRowSelected);
+ }, 200);
+
+
+ });
+
+ hideSpinner();
+
+
+ }
+ }
+ );
};
diff --git a/server/graphql_server/graphql_schema.py b/server/graphql_server/graphql_schema.py
index 7b4a7eac..ff88f203 100755
--- a/server/graphql_server/graphql_schema.py
+++ b/server/graphql_server/graphql_schema.py
@@ -17,36 +17,36 @@ folder = apiPath
# Device ObjectType
class Device(ObjectType):
rowid = Int()
- devMac = String() # This should match devMac, not devMac
- devName = String() # This should match devName, not devName
- devOwner = String() # This should match devOwner, not devOwner
- devType = String() # This should match devType, not devType
- devVendor = String() # This should match devVendor, not devVendor
- devFavorite = Int() # This should match devFavorite, not devFavorite
- devGroup = String() # This should match devGroup, not devGroup
- devComments = String() # This should match devComments, not devComments
- devFirstConnection = String() # This should match devFirstConnection, not devFirstConnection
- devLastConnection = String() # This should match devLastConnection, not devLastConnection
- devLastIP = String() # This should match devLastIP, not devLastIP
- devStaticIP = Int() # This should match devStaticIP, not devStaticIP
- devScan = Int() # This should match devScan, not devScan
- devLogEvents = Int() # This should match devLogEvents, not devLogEvents
- devAlertEvents = Int() # This should match devAlertEvents, not devAlertEvents
- devAlertDeviceDown = Int() # This should match devAlertDeviceDown, not devAlertDown
- devSkipRepeated = Int() # This should match devSkipRepeated, not devSkipRepeated
- devLastNotification = String() # This should match devLastNotification, not devLastNotification
- devPresentLastScan = Int() # This should match devPresentLastScan, not devPresentLastScan
- devNewDevice = Int() # This should match devNewDevice, not devIsNew
- devLocation = String() # This should match devLocation, not devLocation
- devArchived = Int() # This should match devArchived, not devIsArchived
- devNetworkNodeMACADDR = String() # This should match devNetworkNodeMACADDR, not devParentMAC
- devNetworkNodePort = String() # This should match devNetworkNodePort, not devParentPort
- devIcon = String() # This should match devIcon, not devIcon
- devGUID = String() # This should match devGUID, not devGUID
- devNetworkSite = String() # This should match devNetworkSite, not devSite
- devSSID = String() # This should match devSSID, not devSSID
- devSyncHubNodeName = String() # This should match devSyncHubNodeName, not devSyncHubNode
- devSourcePlugin = String() # This should match devSourcePlugin, not devSourcePlugin
+ devMac = String()
+ devName = String()
+ devOwner = String()
+ devType = String()
+ devVendor = String()
+ devFavorite = Int()
+ devGroup = String()
+ devComments = String()
+ devFirstConnection = String()
+ devLastConnection = String()
+ devLastIP = String()
+ devStaticIP = Int()
+ devScan = Int()
+ devLogEvents = Int()
+ devAlertEvents = Int()
+ devAlertDown = Int()
+ devSkipRepeated = Int()
+ devLastNotification = String()
+ devPresentLastScan = Int()
+ devIsNew = Int()
+ devLocation = String()
+ devIsArchived = Int()
+ devParentMAC = String()
+ devParentPort = String()
+ devIcon = String()
+ devGUID = String()
+ devSite = String()
+ devSSID = String()
+ devSyncHubNode = String()
+ devSourcePlugin = String()
class Query(ObjectType):
@@ -68,7 +68,7 @@ class Query(ObjectType):
# Schema Definition
devicesSchema = graphene.Schema(query=Query)
-
+# # Sample query
# $.ajax({
# url: 'php/server/query_graphql.php', // The PHP endpoint that proxies to the GraphQL server
# type: 'POST',