diff --git a/front/devices.php b/front/devices.php
index 5c780ca8..6a0e71ed 100755
--- a/front/devices.php
+++ b/front/devices.php
@@ -364,174 +364,25 @@ function getDeviceStatus(item)
return "Unknown status"
}
-// -----------------------------------------------------------------------------
-function initializeDatatable_n (status) {
-
-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',
- 'devLocation', 'devVendor', 'devNetworkNodePort', 'devGUID', 'devSyncHubNodeName',
- 'devNetworkSite', 'devSSID', 'devSourcePlugin'
-];
-
-let selectedColumns = columnsToFetch.filter(col => tableColumnVisible.includes(col));
-
-
-
-// Construct the GraphQL query
-let graphqlQuery = `
- query {
- devices {
- ${selectedColumns.join('\n')}
- }
- }
-`;
-
-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(response) {
- console.log('GraphQL Response:', response);
-
- // Handle the GraphQL response
- let devicesListAll_JSON = response.data.devices;
- let devicesListAll_JSON_str = JSON.stringify(devicesListAll_JSON);
- setCache('devicesListAll_JSON', devicesListAll_JSON_str);
-
- // Query data
- getDevicesTotals(devicesListAll_JSON);
-
- // Filter the data based on deviceStatus
- var filteredData = filterDataByStatus(devicesListAll_JSON, deviceStatus);
-
- // Convert JSON data into the desired format
- var dataArray = {
- data: filteredData.map(function(item) {
- var originalRow = selectedColumns.map(function(column) {
- return item[column] || "";
- });
-
- var newRow = [];
-
- // Reorder data based on user-defined columns order
- for (index = 0; index < tableColumnOrder.length; index++) {
- newRow.push(originalRow[tableColumnOrder[index]]);
- }
-
- return newRow;
- })
- };
-
- // Initialize DataTable
- if ($.fn.dataTable.isDataTable('#tableDevices')) {
- 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,
- 'pageLength': tableRows,
- 'order': tableOrder,
- 'select': true,
- '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) {
- $(td).html (''+ cellData +'');
- }},
-
- // Handle other column customizations (similar to the original code)
- // Example for IP address formatting:
- { targets: [mapIndx(8)], 'createdCell': function (td, cellData) {
- if (!emptyArr.includes(cellData)) {
- $(td).html (`
- ${cellData}
-
- `);
- } else {
- $(td).html('');
- }
- }}
-
- // Other columns (Status, MAC, Date, etc.) can be similarly customized.
- ],
- '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');?>",
- }
- });
-
- // Event listeners for row selection and saving parameters (same as the original code)
- $('#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 and row selection functionality
- $('#multiEditPlc').append(
- ``
- );
-
- $('#tableDevices').on('click', 'tr', function () {
- setTimeout(function(){
- var anyRowSelected = $('#tableDevices tr.selected').length > 0;
- $('#multiEdit').toggle(anyRowSelected);
- }, 200);
- });
-
- hideSpinner(); // Hide the loading spinner
- },
- error: function(xhr, status, error) {
- console.error('AJAX Error:', error);
- }
-});
-
+// Map column index to column name for GraphQL query
+function mapColumnIndexToFieldName(index) {
+ const columnNames = [
+ "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"
+ ];
+ return columnNames[index] || null;
}
// ---------------------------------------------------------
function initializeDatatable (status) {
-
-
+
if(!status)
{
status = 'my_devices'
@@ -579,323 +430,328 @@ function initializeDatatable (status) {
}
}
- // 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
+
+ var table = $('#tableDevices').DataTable({
+ "serverSide": true,
+ "processing": true,
+ "ajax": {
+ "url": 'php/server/query_graphql.php', // PHP endpoint that proxies to the GraphQL server
+ "type": "POST",
+ "contentType": "application/json",
+ "data": function (d) {
+ // Construct GraphQL query with pagination and sorting options
+ let graphqlQuery = `
+ query devices($options: PageQueryOptionsInput) {
+ devices(options: $options) {
+ 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
+ }
+ count
+ }
}
+ `;
+
+ console.log(d);
+
+
+ // Prepare query variables for pagination, sorting, and search
+ let query = {
+ "operationName": null,
+ "query": graphqlQuery,
+ "variables": {
+ "options": {
+ "page": Math.floor(d.start / d.length) + 1, // Page number (1-based)
+ "limit": parseInt(d.length, 10), // Page size (ensure it's an integer)
+ "sort": d.order && d.order[0] ? [{
+ "field": mapColumnIndexToFieldName(d.order[0].column), // Sort field from DataTable column
+ "order": d.order[0].dir.toUpperCase() // Sort direction (ASC/DESC)
+ }] : [], // Default to an empty array if no sorting is defined
+ "search": d.search.value // Search query
+ }
+ }
+ };
+
+ return JSON.stringify(query); // Send the JSON request
+ },
+ "dataSrc": function (json) {
+ console.log(json);
+
+ return json.devices.devices.map(device => {
+ // Convert each device record into the required DataTable row format
+ const originalRow = [
+ device.devName || "",
+ device.devOwner || "",
+ device.devType || "",
+ device.devIcon || "",
+ device.devFavorite || "",
+ device.devGroup || "",
+ device.devFirstConnection || "",
+ device.devLastConnection || "",
+ device.devLastIP || "",
+ (isRandomMAC(device.devMac)) || "", // Custom logic for randomized MAC
+ getDeviceStatus(device) || "",
+ device.devMac || "", // hidden
+ formatIPlong(device.devLastIP) || "", // IP orderable
+ device.rowid || "",
+ device.devParentMAC || "",
+ getNumberOfChildren(device.devMac, json.devices.devices) || 0,
+ device.devLocation || "",
+ device.devVendor || "",
+ device.devParentPort || 0,
+ device.devGUID || "",
+ device.devSyncHubNode || "",
+ device.devSite || "",
+ device.devSSID || "",
+ device.devSourcePlugin || ""
+ ];
+
+ const newRow = [];
+ // Reorder data based on user-defined columns order
+ for (let index = 0; index < tableColumnOrder.length; index++) {
+ newRow.push(originalRow[tableColumnOrder[index]]);
+ }
+
+ return newRow;
+ });
}
- `;
+ },
+ 'paging' : true,
+ 'lengthChange' : true,
+ 'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
+ 'searching' : true,
- console.log(graphqlQuery);
+ 'ordering' : true,
+ 'info' : true,
+ 'autoWidth' : false,
+ // Parameters
+ 'pageLength' : tableRows,
+ 'order' : tableOrder,
+ 'select' : true, // Enable selection
- $.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) {
+ '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) },
- // refresh devices cache
- devicesListAll_JSON = result["devices"];
- console.log(devicesListAll_JSON);
-
- 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);
-
- // 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 ('');
- }
- } },
+ // Device Name
+ {targets: [mapIndx(0)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
- // 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));
- } },
+ // console.log(cellData)
+ $(td).html (''+ cellData +'');
+ } },
- // Random MAC
- {targets: [mapIndx(9)],
- 'createdCell': function (td, cellData, rowData, row, col) {
- // console.log(cellData)
- if (cellData == 1){
- $(td).html ('');
- } else {
- $(td).html ('');
- }
- } },
+ // Connected Devices
+ {targets: [mapIndx(15)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
- // Status color
- {targets: [mapIndx(10)],
- '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 (``)
+ }
+
+ } },
- devData = getDeviceDataByMac(rowData[mapIndx(11)])
+ // Icon
+ {targets: [mapIndx(3)],
+ 'createdCell': function (td, cellData, rowData, row, col) {
+
+ if (!emptyArr.includes(cellData)){
+ $(td).html (atob(cellData));
+ } else {
+ $(td).html ('');
+ }
+ } },
- 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('-', '')}`);
- } },
- ],
+ // 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 ('');
+ }
+ } },
- // 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');?>",
- }
- });
+ // 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' : {
+ 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');?>",
+ },
+ initComplete: function (settings, JSON) {
+ // Handle any additional interactions or event listeners as required
// 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
- } );
+ 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(
- ``)
+ // add multi-edit button
+ $('#multiEditPlc').append(
+ ``)
- // 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;
+ // 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);
+ // Toggle visibility of element with ID 'multiEdit'
+ $('#multiEdit').toggle(anyRowSelected);
+ }, 100);
+
+ });
-
- });
-
- hideSpinner();
-
-
- }
+
+ hideSpinner();
+
}
- );
-};
+
+ });
+
+
+}
+
+
+
// -----------------------------------------------------------------------------
diff --git a/front/js/common.js b/front/js/common.js
index 6f440381..3c787cc5 100755
--- a/front/js/common.js
+++ b/front/js/common.js
@@ -970,6 +970,19 @@ function getGuid() {
// -----------------------------------------------------------------------------
// Loading Spinner overlay
// -----------------------------------------------------------------------------
+spinnerHtml = `
+
+
+ `
+
function showSpinner(stringKey='Loading')
{
@@ -988,20 +1001,7 @@ function showSpinner(stringKey='Loading')
$("#loadingSpinner").show();
}
else{
- html = `
-
-
- `
-
- $(".wrapper").append(html)
+ $(".wrapper").append(spinnerHtml.replace('_text_',text))
}
}
// -----------------------------------------------------------------------------
diff --git a/server/graphql_server/graphql_schema.py b/server/graphql_server/graphql_schema.py
index ff88f203..bd0a6035 100755
--- a/server/graphql_server/graphql_schema.py
+++ b/server/graphql_server/graphql_schema.py
@@ -1,9 +1,8 @@
import graphene
-from graphene import ObjectType, String, Int, Boolean, Field, List
+from graphene import ObjectType, String, Int, Boolean, List, Field, InputObjectType
import json
import sys
-
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
@@ -14,6 +13,17 @@ from const import apiPath
# Define a base URL with the user's home directory
folder = apiPath
+# Pagination and Sorting Input Types
+class SortOptionsInput(InputObjectType):
+ field = String()
+ order = String()
+
+class PageQueryOptionsInput(InputObjectType):
+ page = Int()
+ limit = Int()
+ sort = List(SortOptionsInput)
+ search = String()
+
# Device ObjectType
class Device(ObjectType):
rowid = Int()
@@ -48,50 +58,49 @@ class Device(ObjectType):
devSyncHubNode = String()
devSourcePlugin = String()
-
-class Query(ObjectType):
+class DeviceResult(ObjectType):
devices = List(Device)
+ count = Int()
- def resolve_devices(self, info):
- # Load JSON data only when the query executes
+# Define Query Type with Pagination Support
+class Query(ObjectType):
+ devices = Field(DeviceResult, options=PageQueryOptionsInput())
+
+ def resolve_devices(self, info, options=None):
try:
with open(folder + 'table_devices.json', 'r') as f:
devices_data = json.load(f)["data"]
except (FileNotFoundError, json.JSONDecodeError) as e:
- mylog('error', f'[graphql_schema] Error loading devices data: {e}')
- return []
+ mylog('none', f'[graphql_schema] Error loading devices data: {e}')
+ return DeviceResult(devices=[], count=0)
- return devices_data # Directly return the data without mapping
+ total_count = len(devices_data)
+ # Apply pagination and sorting if options are provided
+ if options:
+ # Implement pagination and sorting here
+ if options.page and options.limit:
+ start = (options.page - 1) * options.limit
+ end = start + options.limit
+ devices_data = devices_data[start:end]
+
+ if options.sort:
+ for sort_option in options.sort:
+ devices_data = sorted(
+ devices_data,
+ key=lambda x: x.get(sort_option.field),
+ reverse=(sort_option.order.lower() == "desc")
+ )
+
+ # Filter data if a search term is provided
+ if options.search:
+ devices_data = [
+ device for device in devices_data
+ if options.search.lower() in device.get("devName", "").lower()
+ ]
+
+ return DeviceResult(devices=devices_data, count=total_count)
# 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',
-# contentType: 'application/json', // Send the data as JSON
-# data: JSON.stringify({
-# query: `
-# query {
-# devices {
-# devMac
-# devName
-# devLastConnection
-# devArchived
-# }
-# }
-# `, // GraphQL query for plugins
-# variables: {} // Optional, pass variables if needed
-# }),
-# success: function(response) {
-# console.log('GraphQL Response:', response);
-# // Handle the GraphQL response here
-# },
-# error: function(xhr, status, error) {
-# console.error('AJAX Error:', error);
-# // Handle errors here
-# }
-# });