mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-02 08:12:21 -07:00
refactor UI backend calls to python endpoints
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
function getApiBase()
|
||||
{
|
||||
apiBase = getSetting("BACKEND_API_URL");
|
||||
let apiBase = getSetting("BACKEND_API_URL");
|
||||
|
||||
if(apiBase == "")
|
||||
{
|
||||
|
||||
@@ -686,26 +686,43 @@ function numberArrayFromString(data)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function saveData(functionName, id, value) {
|
||||
// Update network parent/child relationship (network tree)
|
||||
function updateNetworkLeaf(leafMac, parentMac) {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/device/${leafMac}/update-column`;
|
||||
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: "php/server/devices.php",
|
||||
data: { action: functionName, id: id, value:value },
|
||||
success: function(data) {
|
||||
|
||||
if(sanitize(data) == 'OK')
|
||||
{
|
||||
showMessage("Saved")
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
} else
|
||||
{
|
||||
showMessage("ERROR")
|
||||
}
|
||||
|
||||
method: "POST",
|
||||
url: url,
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ columnName: "devParentMAC", columnValue: parentMac }),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
if(response.success) {
|
||||
showMessage("Saved");
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
} else {
|
||||
showMessage("ERROR: " + (response.error || "Unknown error"));
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error updating network leaf:", status, error);
|
||||
showMessage("ERROR: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Legacy function wrapper for backward compatibility
|
||||
function saveData(functionName, id, value) {
|
||||
if (functionName === 'updateNetworkLeaf') {
|
||||
updateNetworkLeaf(id, value);
|
||||
} else {
|
||||
console.warn("saveData called with unknown functionName:", functionName);
|
||||
showMessage("ERROR: Unknown function");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -32,27 +32,62 @@ function renderList(
|
||||
// remove first item containing the SQL query
|
||||
options.shift();
|
||||
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${btoa(encodeURIComponent(sqlQuery))}`;
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/read`;
|
||||
|
||||
$.get(apiUrl, function (sqlOptionsData) {
|
||||
|
||||
// Parse the returned SQL data
|
||||
const sqlOption = JSON.parse(sqlOptionsData);
|
||||
// Unicode-safe base64 encoding
|
||||
const base64Sql = btoa(unescape(encodeURIComponent(sqlQuery)));
|
||||
|
||||
// Concatenate options from SQL query with the supplied options
|
||||
options = options.concat(sqlOption);
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ rawSql: base64Sql }),
|
||||
contentType: "application/json",
|
||||
success: function(data) {
|
||||
console.log("SQL query response:", data);
|
||||
|
||||
// Process the combined options
|
||||
setTimeout(() => {
|
||||
processDataCallback(
|
||||
options,
|
||||
valuesArray,
|
||||
targetField,
|
||||
transformers,
|
||||
placeholder
|
||||
);
|
||||
}, 1);
|
||||
// Parse the returned SQL data
|
||||
let sqlOption = [];
|
||||
if (data && data.success && data.results) {
|
||||
sqlOption = data.results;
|
||||
} else if (Array.isArray(data)) {
|
||||
// Fallback for direct array response
|
||||
sqlOption = data;
|
||||
} else {
|
||||
console.warn("Unexpected response format:", data);
|
||||
}
|
||||
|
||||
// Concatenate options from SQL query with the supplied options
|
||||
options = options.concat(sqlOption);
|
||||
|
||||
console.log("Combined options:", options);
|
||||
|
||||
// Process the combined options
|
||||
setTimeout(() => {
|
||||
processDataCallback(
|
||||
options,
|
||||
valuesArray,
|
||||
targetField,
|
||||
transformers,
|
||||
placeholder
|
||||
);
|
||||
}, 1);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error loading SQL options:", status, error, xhr.responseJSON);
|
||||
// Process original options anyway
|
||||
setTimeout(() => {
|
||||
processDataCallback(
|
||||
options,
|
||||
valuesArray,
|
||||
targetField,
|
||||
transformers,
|
||||
placeholder
|
||||
);
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// No SQL query, directly process the supplied options
|
||||
@@ -85,7 +120,7 @@ function renderList(
|
||||
// Check if database is locked
|
||||
function checkDbLock() {
|
||||
$.ajax({
|
||||
url: "php/server/query_logs.php?file=db_is_locked.log",
|
||||
url: "php/server/query_logs.php?file=db_is_locked.log",
|
||||
type: "GET",
|
||||
|
||||
success: function (response) {
|
||||
|
||||
@@ -33,13 +33,23 @@ function deleteDevice() {
|
||||
// Check MAC
|
||||
mac = getMac()
|
||||
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteDevice&mac=' + mac, function (msg) {
|
||||
showMessage(msg);
|
||||
});
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/device/${mac}/delete`;
|
||||
|
||||
// refresh API
|
||||
updateApi("devices,appevents")
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "Device deleted successfully" : (response.error || "Unknown error"));
|
||||
updateApi("devices,appevents");
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting device:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -47,16 +57,23 @@ function deleteDeviceByMac(mac) {
|
||||
// Check MAC
|
||||
mac = getMac()
|
||||
|
||||
// alert(mac)
|
||||
// return;
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/device/${mac}/delete`;
|
||||
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteDevice&mac=' + mac, function (msg) {
|
||||
showMessage(msg);
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "Device deleted successfully" : (response.error || "Unknown error"));
|
||||
updateApi("devices,appevents");
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting device:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
|
||||
// refresh API
|
||||
updateApi("devices,appevents")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -443,12 +443,14 @@ function safeDecodeURIComponent(content) {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function to check for notifications
|
||||
function checkNotification() {
|
||||
const notificationEndpoint = 'php/server/utilNotification.php?action=get_unread_notifications';
|
||||
const phpEndpoint = 'php/server/utilNotification.php';
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const notificationEndpoint = `${apiBase}/messaging/in-app/unread`;
|
||||
|
||||
$.ajax({
|
||||
url: notificationEndpoint,
|
||||
type: 'GET',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
// console.log(response);
|
||||
|
||||
@@ -469,14 +471,13 @@ function checkNotification() {
|
||||
if($("#modal-ok").is(":visible") == false)
|
||||
{
|
||||
showModalOK("Notification", decodedContent, function() {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
// Mark the notification as read
|
||||
$.ajax({
|
||||
url: phpEndpoint,
|
||||
type: 'GET',
|
||||
data: {
|
||||
action: 'mark_notification_as_read',
|
||||
guid: oldestInterruptNotification.guid
|
||||
},
|
||||
url: `${apiBase}/messaging/in-app/read/${oldestInterruptNotification.guid}`,
|
||||
type: 'POST',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
// After marking the notification as read, check for the next one
|
||||
@@ -585,20 +586,21 @@ setInterval(checkNotification, 3000);
|
||||
// User notification handling methods
|
||||
// --------------------------------------------------
|
||||
|
||||
const phpEndpoint = 'php/server/utilNotification.php';
|
||||
|
||||
// --------------------------------------------------
|
||||
// Write a notification
|
||||
function write_notification(content, level) {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
|
||||
$.ajax({
|
||||
url: phpEndpoint, // Change this to the path of your PHP script
|
||||
type: 'GET',
|
||||
data: {
|
||||
action: 'write_notification',
|
||||
url: `${apiBase}/messaging/in-app/write`,
|
||||
type: 'POST',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({
|
||||
content: content,
|
||||
level: level
|
||||
},
|
||||
}),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
console.log('Notification written successfully.');
|
||||
},
|
||||
@@ -609,53 +611,58 @@ function write_notification(content, level) {
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Write a notification
|
||||
// Mark a notification as read
|
||||
function markNotificationAsRead(guid) {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
|
||||
$.ajax({
|
||||
url: phpEndpoint,
|
||||
type: 'GET',
|
||||
data: {
|
||||
action: 'mark_notification_as_read',
|
||||
guid: guid
|
||||
},
|
||||
url: `${apiBase}/messaging/in-app/read/${guid}`,
|
||||
type: 'POST',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
// Perform any further actions after marking the notification as read here
|
||||
showMessage(getString("Gen_Okay"))
|
||||
console.log("Mark notification response:", response);
|
||||
if (response.success) {
|
||||
showMessage(getString("Gen_Okay"));
|
||||
// Reload the page to refresh notifications
|
||||
setTimeout(() => window.location.reload(), 500);
|
||||
} else {
|
||||
console.error("Failed to mark notification as read:", response.error);
|
||||
showMessage("Error: " + (response.error || "Unknown error"));
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error marking notification as read:", status, error);
|
||||
console.error("Error marking notification as read:", status, error, xhr.responseJSON);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
},
|
||||
complete: function() {
|
||||
// Perform any cleanup tasks here
|
||||
// Perform any cleanup tasks here
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// Remove a notification
|
||||
function removeNotification(guid) {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
|
||||
$.ajax({
|
||||
url: phpEndpoint,
|
||||
type: 'GET',
|
||||
data: {
|
||||
action: 'remove_notification',
|
||||
guid: guid
|
||||
},
|
||||
url: `${apiBase}/messaging/in-app/delete/${guid}`,
|
||||
type: 'DELETE',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
// Perform any further actions after marking the notification as read here
|
||||
showMessage(getString("Gen_Okay"))
|
||||
console.log(response);
|
||||
// Perform any further actions after removing the notification here
|
||||
showMessage(getString("Gen_Okay"))
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error removing notification:", status, error);
|
||||
console.error("Error removing notification:", status, error);
|
||||
},
|
||||
complete: function() {
|
||||
// Perform any cleanup tasks here
|
||||
// Perform any cleanup tasks here
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -378,14 +378,27 @@ function overwriteIconType()
|
||||
)
|
||||
`;
|
||||
|
||||
const apiUrl = `php/server/dbHelper.php?action=write&rawSql=${btoa(encodeURIComponent(rawSql))}`;
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/write`;
|
||||
|
||||
$.get(apiUrl, function(response) {
|
||||
if (response === 'OK') {
|
||||
showMessage (response);
|
||||
updateApi("devices")
|
||||
} else {
|
||||
showMessage (response, 3000, "modal_red");
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ rawSql: btoa(unescape(encodeURIComponent(rawSql))) }),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showMessage("OK");
|
||||
updateApi("devices");
|
||||
} else {
|
||||
showMessage(response.error || "Unknown error", 3000, "modal_red");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error updating icons:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error), 3000, "modal_red");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -327,10 +327,22 @@ function askDeleteDevicesWithEmptyMACs () {
|
||||
// -----------------------------------------------------------
|
||||
function deleteDevicesWithEmptyMACs()
|
||||
{
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteAllWithEmptyMACs', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] All devices witout a Mac manually deleted`, 'info')
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/devices/empty-macs`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "Devices deleted successfully" : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] All devices without a Mac manually deleted`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting devices:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -344,10 +356,24 @@ function askDeleteAllDevices () {
|
||||
// -----------------------------------------------------------
|
||||
function deleteAllDevices()
|
||||
{
|
||||
// Delete device
|
||||
$.get('php/server/devices.php?action=deleteAllDevices', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] All devices manually deleted`, 'info')
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/devices`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ macs: null }),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "All devices deleted successfully" : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] All devices manually deleted`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting devices:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -361,10 +387,22 @@ function askDeleteUnknown () {
|
||||
// -----------------------------------------------------------
|
||||
function deleteUnknownDevices()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteUnknownDevices', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Unknown devices manually deleted`, 'info')
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/devices/unknown`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "Unknown devices deleted successfully" : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] Unknown devices manually deleted`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting unknown devices:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -378,10 +416,22 @@ function askDeleteEvents () {
|
||||
// -----------------------------------------------------------
|
||||
function deleteEvents()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteEvents', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Events manually deleted (all)`, 'info')
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/events`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "All events deleted successfully" : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] Events manually deleted (all)`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting events:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -395,10 +445,22 @@ function askDeleteEvents30 () {
|
||||
// -----------------------------------------------------------
|
||||
function deleteEvents30()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteEvents30', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Events manually deleted (last 30 days kep)`, 'info')
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/events/30`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "Events older than 30 days deleted successfully" : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] Events manually deleted (last 30 days kept)`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting events:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -411,9 +473,21 @@ function askDeleteActHistory () {
|
||||
}
|
||||
function deleteActHistory()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=deleteActHistory', function(msg) {
|
||||
showMessage (msg);
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/history`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "DELETE",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? "History deleted successfully" : (response.error || "Unknown error"));
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting history:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -466,8 +540,47 @@ function DownloadWorkflows()
|
||||
// Export CSV
|
||||
function ExportCSV()
|
||||
{
|
||||
// Execute
|
||||
openInNewTab("php/server/devices.php?action=ExportCSV")
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/devices/export/csv`;
|
||||
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiToken}`
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
return response.json().then(err => {
|
||||
throw new Error(err.error || 'Export failed');
|
||||
});
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(blob => {
|
||||
const downloadUrl = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = downloadUrl;
|
||||
a.download = 'devices.csv';
|
||||
document.body.appendChild(a);
|
||||
|
||||
// Trigger download
|
||||
a.click();
|
||||
|
||||
// Cleanup after a short delay
|
||||
setTimeout(() => {
|
||||
window.URL.revokeObjectURL(downloadUrl);
|
||||
document.body.removeChild(a);
|
||||
}, 100);
|
||||
|
||||
showMessage('Export completed successfully');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Export error:', error);
|
||||
showMessage('Error: ' + error.message);
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
@@ -479,10 +592,22 @@ function askImportCSV() {
|
||||
}
|
||||
function ImportCSV()
|
||||
{
|
||||
// Execute
|
||||
$.get('php/server/devices.php?action=ImportCSV', function(msg) {
|
||||
showMessage (msg);
|
||||
write_notification(`[Maintenance] Devices imported from CSV file`, 'info')
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/devices/import`;
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
showMessage(response.success ? (response.message || "Devices imported successfully") : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] Devices imported from CSV file`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error importing devices:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -498,20 +623,30 @@ function askImportPastedCSV() {
|
||||
function ImportPastedCSV()
|
||||
{
|
||||
var csv = $('#modal-input-textarea').val();
|
||||
|
||||
console.log(csv);
|
||||
|
||||
csvBase64 = utf8ToBase64(csv);
|
||||
|
||||
console.log(csvBase64);
|
||||
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/devices/import`;
|
||||
|
||||
$.post('php/server/devices.php?action=ImportCSV', { content: csvBase64 }, function(msg) {
|
||||
showMessage(msg);
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ content: csvBase64 }),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
showMessage(response.success ? (response.message || "Devices imported successfully") : (response.error || "Unknown error"));
|
||||
write_notification(`[Maintenance] Devices imported from pasted content`, 'info');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error importing devices:", status, error);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/language/lang.php';
|
||||
?>
|
||||
|
||||
<div class="col-md-12">
|
||||
@@ -331,7 +332,8 @@
|
||||
columnValue = inputElement.is(':checked') ? 1 : 0;
|
||||
} else {
|
||||
// For other input types (like textboxes), simply retrieve their values
|
||||
columnValue = encodeURIComponent(inputElement.val());
|
||||
// Don't encode icons (already base64) or other pre-encoded values
|
||||
columnValue = inputElement.val();
|
||||
}
|
||||
|
||||
var targetColumns = inputElement.attr('data-my-targetColumns');
|
||||
@@ -359,10 +361,40 @@
|
||||
// newTargetColumnValue: Specifies the new value to be assigned to the specified column(s).
|
||||
function executeAction(action, whereColumnName, key, targetColumns, newTargetColumnValue )
|
||||
{
|
||||
$.get(`php/server/dbHelper.php?action=${action}&dbtable=Devices&columnName=${whereColumnName}&id=${key}&columns=${targetColumns}&values=${newTargetColumnValue}`, function(data) {
|
||||
// console.log(data);
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/${action}`;
|
||||
|
||||
if (sanitize(data) == 'OK') {
|
||||
// Convert comma-separated string to array if needed
|
||||
let idArray = key;
|
||||
if (typeof key === 'string' && key.includes(',')) {
|
||||
idArray = key.split(',');
|
||||
} else if (!Array.isArray(key)) {
|
||||
idArray = [key];
|
||||
}
|
||||
|
||||
// Build request data based on action type
|
||||
const requestData = {
|
||||
dbtable: "Devices",
|
||||
columnName: whereColumnName,
|
||||
id: idArray
|
||||
};
|
||||
|
||||
// Only include columns and values for update action
|
||||
if (action === "update") {
|
||||
// Ensure columns and values are arrays
|
||||
requestData.columns = Array.isArray(targetColumns) ? targetColumns : [targetColumns];
|
||||
requestData.values = Array.isArray(newTargetColumnValue) ? newTargetColumnValue : [newTargetColumnValue];
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify(requestData),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showMessage(getString('Gen_DataUpdatedUITakesTime'));
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
@@ -370,12 +402,18 @@ function executeAction(action, whereColumnName, key, targetColumns, newTargetCol
|
||||
// update API endpoints to refresh the UI
|
||||
updateApi("devices,appevents")
|
||||
|
||||
write_notification(`[Multi edit] Executed "${action}" on Columns "${targetColumns}" matching "${key}"`, 'info')
|
||||
const columnsMsg = targetColumns ? ` on Columns "${targetColumns}"` : '';
|
||||
write_notification(`[Multi edit] Executed "${action}"${columnsMsg} matching "${key}"`, 'info')
|
||||
|
||||
} else {
|
||||
console.error(data);
|
||||
showMessage(getString('Gen_LockedDB'));
|
||||
console.error(response.error || "Unknown error");
|
||||
showMessage(response.error || getString('Gen_LockedDB'));
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error executing action:", status, error, xhr.responseJSON);
|
||||
showMessage("Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -101,13 +101,25 @@
|
||||
ON (t1.node_mac = t2.node_mac_2)
|
||||
`;
|
||||
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${btoa(encodeURIComponent(rawSql))}`;
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/read`;
|
||||
|
||||
$.get(apiUrl, function (data) {
|
||||
const nodes = JSON.parse(data);
|
||||
renderNetworkTabs(nodes);
|
||||
loadUnassignedDevices();
|
||||
checkTabsOverflow();
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ rawSql: btoa(unescape(encodeURIComponent(rawSql))) }),
|
||||
contentType: "application/json",
|
||||
success: function(data) {
|
||||
const nodes = data.results || [];
|
||||
renderNetworkTabs(nodes);
|
||||
loadUnassignedDevices();
|
||||
checkTabsOverflow();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error loading network nodes:", status, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -222,22 +234,30 @@
|
||||
|
||||
// ----------------------------------------------------
|
||||
function loadDeviceTable({ sql, containerSelector, tableId, wrapperHtml = null, assignMode = true }) {
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${btoa(encodeURIComponent(sql))}`;
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/read`;
|
||||
|
||||
$.get(apiUrl, function (data) {
|
||||
const devices = JSON.parse(data);
|
||||
const $container = $(containerSelector);
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ rawSql: btoa(unescape(encodeURIComponent(sql))) }),
|
||||
contentType: "application/json",
|
||||
success: function(data) {
|
||||
const devices = data.results || [];
|
||||
const $container = $(containerSelector);
|
||||
|
||||
// end if nothing to show
|
||||
if(devices.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// end if nothing to show
|
||||
if(devices.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$container.html(wrapperHtml);
|
||||
$container.html(wrapperHtml);
|
||||
|
||||
const $table = $(`#${tableId}`);
|
||||
const $table = $(`#${tableId}`);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -313,15 +333,19 @@
|
||||
createdRow: function (row, data) {
|
||||
$(row).attr('data-mac', data.devMac);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ($.fn.DataTable.isDataTable($table)) {
|
||||
$table.DataTable(tableConfig).clear().rows.add(devices).draw();
|
||||
} else {
|
||||
$table.DataTable(tableConfig);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error loading device table:", status, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
function loadUnassignedDevices() {
|
||||
@@ -409,25 +433,31 @@
|
||||
FROM Devices a
|
||||
`;
|
||||
|
||||
const apiUrl = `php/server/dbHelper.php?action=read&rawSql=${btoa(encodeURIComponent(rawSql))}`;
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/read`;
|
||||
|
||||
$.get(apiUrl, function (data) {
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({ rawSql: btoa(unescape(encodeURIComponent(rawSql))) }),
|
||||
contentType: "application/json",
|
||||
success: function(data) {
|
||||
console.log(data);
|
||||
|
||||
console.log(data);
|
||||
const allDevices = data.results || [];
|
||||
|
||||
const parsed = JSON.parse(data);
|
||||
const allDevices = parsed;
|
||||
|
||||
console.log(allDevices);
|
||||
console.log(allDevices);
|
||||
|
||||
|
||||
if (!allDevices || allDevices.length === 0) {
|
||||
showModalOK(getString('Gen_Warning'), getString('Network_NoDevices'));
|
||||
return;
|
||||
}
|
||||
if (!allDevices || allDevices.length === 0) {
|
||||
showModalOK(getString('Gen_Warning'), getString('Network_NoDevices'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Count totals for UI
|
||||
let archivedCount = 0;
|
||||
// Count totals for UI
|
||||
let archivedCount = 0;
|
||||
let offlineCount = 0;
|
||||
|
||||
allDevices.forEach(device => {
|
||||
@@ -488,7 +518,11 @@
|
||||
initTree(getHierarchy());
|
||||
loadNetworkNodes();
|
||||
attachTreeEvents();
|
||||
});
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error loading topology data:", status, error);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@
|
||||
"Maintenance_Tool_ExportCSV": "Devices export (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Devices export (csv)",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Are you sure you want to generate a CSV file?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Generate a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. You can also trigger this by accessing this URL <code>your_NetAlertX_url/php/server/devices.php?action=ExportCSV</code> or by enabling the <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a> plugin.",
|
||||
"Maintenance_Tool_ExportCSV_text": "Generate a CSV (comma separated value) file containing the list of Devices including the Network relationships between Network Nodes and connected devices. You can also trigger this by enabling the <a href=\"settings.php#CSVBCKP_header\">CSV Backup</a> plugin.",
|
||||
"Maintenance_Tool_ImportCSV": "Devices Import (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Devices Import (csv)",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Are you sure you want to import the CSV file? This will completely <b>overwrite</b> the devices in your database.",
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-tabs-custom plugin-content" style="margin-bottom: 0px;">
|
||||
|
||||
|
||||
<ul id="tabs-location" class="nav nav-tabs col-sm-2 ">
|
||||
<!-- PLACEHOLDER -->
|
||||
</ul>
|
||||
<div id="tabs-content-location-wrap" class="tab-content col-sm-10">
|
||||
<div id="tabs-content-location" class="tab-content col-sm-12">
|
||||
</ul>
|
||||
<div id="tabs-content-location-wrap" class="tab-content col-sm-10">
|
||||
<div id="tabs-content-location" class="tab-content col-sm-12">
|
||||
<!-- PLACEHOLDER -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<script>
|
||||
@@ -44,9 +44,9 @@ function initMacFilter() {
|
||||
else
|
||||
{
|
||||
$("#txtMacFilter").val("--");
|
||||
}
|
||||
}
|
||||
|
||||
return mac;
|
||||
return mac;
|
||||
}
|
||||
|
||||
// -----------------------------------------------
|
||||
@@ -85,7 +85,7 @@ function initFields() {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get form control according to the column definition from config.json > database_column_definitions
|
||||
function getFormControl(dbColumnDef, value, index) {
|
||||
function getFormControl(dbColumnDef, value, index) {
|
||||
|
||||
result = ''
|
||||
|
||||
@@ -94,18 +94,18 @@ function getFormControl(dbColumnDef, value, index) {
|
||||
value = dbColumnDef.mapped_to_column_data.value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
result = processColumnValue(dbColumnDef, value, index, dbColumnDef.type)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Process column value
|
||||
// Process column value
|
||||
function processColumnValue(dbColumnDef, value, index, type) {
|
||||
if (type.includes('.')) {
|
||||
const typeParts = type.split('.');
|
||||
|
||||
|
||||
// recursion
|
||||
for (const typePart of typeParts) {
|
||||
value = processColumnValue(dbColumnDef, value, index, typePart)
|
||||
@@ -115,13 +115,13 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
// pick form control based on the supplied type
|
||||
switch(type)
|
||||
{
|
||||
case 'label':
|
||||
case 'label':
|
||||
value = `<span>${value}<span>`;
|
||||
break;
|
||||
case 'none':
|
||||
case 'none':
|
||||
value = `${value}`;
|
||||
break;
|
||||
case 'textarea_readonly':
|
||||
case 'textarea_readonly':
|
||||
value = `<textarea cols="70" rows="3" wrap="off" readonly style="white-space: pre-wrap;">
|
||||
${value.replace(/^b'(.*)'$/gm, '$1').replace(/\\n/g, '\n').replace(/\\r/g, '\r')}
|
||||
</textarea>`;
|
||||
@@ -143,7 +143,7 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
value = `<span><a href="${value}" target="_blank">${value}</a><span>`;
|
||||
break;
|
||||
case 'url_http_https':
|
||||
|
||||
|
||||
value = `<span>
|
||||
<a href="http://${value}" target="_blank">
|
||||
<i class="fa fa-lock-open "></i>
|
||||
@@ -155,9 +155,9 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
<span>`;
|
||||
break;
|
||||
case 'device_name_mac':
|
||||
value = `<div class="text-center"> ${value}
|
||||
<br/>
|
||||
(${createDeviceLink(value)})
|
||||
value = `<div class="text-center"> ${value}
|
||||
<br/>
|
||||
(${createDeviceLink(value)})
|
||||
</div>`;
|
||||
break;
|
||||
case 'device_mac':
|
||||
@@ -166,12 +166,12 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
case 'device_ip':
|
||||
value = `<span class="anonymizeIp"><a href="#" onclick="navigateToDeviceWithIp('${value}')" >${value}</a><span>`;
|
||||
break;
|
||||
case 'threshold':
|
||||
case 'threshold':
|
||||
|
||||
valueTmp = ''
|
||||
|
||||
$.each(dbColumnDef.options, function(index, obj) {
|
||||
if(Number(value) < Number(obj.maximum) && valueTmp == '')
|
||||
if(Number(value) < Number(obj.maximum) && valueTmp == '')
|
||||
{
|
||||
valueTmp = `<div class="thresholdFormControl" style="background-color:${obj.hexColor}">${value}</div>`
|
||||
// return;
|
||||
@@ -181,7 +181,7 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
value = valueTmp;
|
||||
|
||||
break;
|
||||
case 'replace':
|
||||
case 'replace':
|
||||
$.each(dbColumnDef.options, function(index, obj) {
|
||||
if(value == obj.equals)
|
||||
{
|
||||
@@ -190,22 +190,22 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
});
|
||||
break;
|
||||
case 'regex':
|
||||
|
||||
|
||||
for (const option of dbColumnDef.options) {
|
||||
if (option.type === type) {
|
||||
|
||||
|
||||
const regexPattern = new RegExp(option.param);
|
||||
const match = value.match(regexPattern);
|
||||
if (match) {
|
||||
// Return the first match
|
||||
value = match[0];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'eval':
|
||||
|
||||
|
||||
for (const option of dbColumnDef.options) {
|
||||
if (option.type === type) {
|
||||
// console.log(option.param)
|
||||
@@ -213,9 +213,9 @@ function processColumnValue(dbColumnDef, value, index, type) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
value = value + `<div style='text-align:center' title="${getString("Plugins_no_control")}"><i class='fa-solid fa-circle-question'></i></div>` ;
|
||||
value = value + `<div style='text-align:center' title="${getString("Plugins_no_control")}"><i class='fa-solid fa-circle-question'></i></div>` ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,22 +236,38 @@ function genericSaveData (id) {
|
||||
console.log(index)
|
||||
console.log(columnValue)
|
||||
|
||||
$.get(`php/server/dbHelper.php?action=update&dbtable=Plugins_Objects&columnName=Index&id=${index}&columns=UserData&values=${columnValue}`, function(data) {
|
||||
|
||||
// var result = JSON.parse(data);
|
||||
// console.log(data)
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/update`;
|
||||
|
||||
if(sanitize(data) == 'OK')
|
||||
{
|
||||
showMessage('<?= lang('Gen_DataUpdatedUITakesTime');?>')
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
} else
|
||||
{
|
||||
showMessage('<?= lang('Gen_LockedDB');?>')
|
||||
}
|
||||
|
||||
});
|
||||
$.ajax({
|
||||
url,
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({
|
||||
dbtable: "Plugins_Objects",
|
||||
columnName: "Index",
|
||||
id: index,
|
||||
columns: "UserData",
|
||||
values: columnValue
|
||||
}),
|
||||
contentType: "application/json",
|
||||
success: function(response) {
|
||||
if(response.success)
|
||||
{
|
||||
showMessage('<?= lang('Gen_DataUpdatedUITakesTime');?>')
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
} else
|
||||
{
|
||||
showMessage('<?= lang('Gen_LockedDB');?>')
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error saving data:", status, error);
|
||||
showMessage('<?= lang('Gen_LockedDB');?>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -307,15 +323,15 @@ function generateTabs() {
|
||||
stats = createTabContent(pluginObj, assignActive); // Create the content for each tab
|
||||
|
||||
if(stats.objectDataCount > 0)
|
||||
{
|
||||
{
|
||||
createTabHeader(pluginObj, stats, assignActive); // Create the header for each tab
|
||||
assignActive = false; // only mark first with content active
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
hideSpinner()
|
||||
}
|
||||
|
||||
@@ -329,7 +345,7 @@ function resetTabs() {
|
||||
// left headers
|
||||
function createTabHeader(pluginObj, stats, assignActive) {
|
||||
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
||||
|
||||
|
||||
// Determine the active class for the first tab
|
||||
assignActive ? activeClass = "active" : activeClass = "";
|
||||
|
||||
@@ -338,12 +354,12 @@ function createTabHeader(pluginObj, stats, assignActive) {
|
||||
<li class="left-nav ${activeClass} ">
|
||||
<a class="col-sm-12 textOverflow" href="#${prefix}" data-plugin-prefix="${prefix}" id="${prefix}_id" data-toggle="tab">
|
||||
${getString(`${prefix}_icon`)} ${getString(`${prefix}_display_name`)}
|
||||
|
||||
|
||||
</a>
|
||||
${stats.objectDataCount > 0 ? `<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" >${stats.objectDataCount}</span></div>` : ""}
|
||||
${stats.objectDataCount > 0 ? `<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" >${stats.objectDataCount}</span></div>` : ""}
|
||||
</li>
|
||||
`);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
@@ -351,7 +367,7 @@ function createTabHeader(pluginObj, stats, assignActive) {
|
||||
function createTabContent(pluginObj, assignActive) {
|
||||
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
||||
const colDefinitions = getColumnDefinitions(pluginObj); // Get column definitions for DataTables
|
||||
|
||||
|
||||
// Get data for events, objects, and history related to the plugin
|
||||
const objectData = getObjectData(prefix, colDefinitions, pluginObj);
|
||||
const eventData = getEventData(prefix, colDefinitions, pluginObj);
|
||||
@@ -362,9 +378,9 @@ function createTabContent(pluginObj, assignActive) {
|
||||
<div id="${prefix}" class="tab-pane ${objectData.length > 0 && assignActive? 'active' : ''}">
|
||||
${generateTabNavigation(prefix, objectData.length, eventData.length, historyData.length)} <!-- Create tab navigation -->
|
||||
<div class="tab-content">
|
||||
${generateDataTable(prefix, 'Objects', objectData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'Events', eventData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'History', historyData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'Objects', objectData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'Events', eventData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'History', historyData, colDefinitions)}
|
||||
</div>
|
||||
<div class='plugins-description'>
|
||||
${getString(`${prefix}_description`)} <!-- Display the plugin description -->
|
||||
@@ -376,10 +392,10 @@ function createTabContent(pluginObj, assignActive) {
|
||||
// Initialize DataTables for the respective sections
|
||||
initializeDataTables(prefix, objectData, eventData, historyData, colDefinitions);
|
||||
|
||||
return {
|
||||
"objectDataCount": objectData.length,
|
||||
"eventDataCount": eventData.length,
|
||||
"historyDataCount": historyData.length
|
||||
return {
|
||||
"objectDataCount": objectData.length,
|
||||
"eventDataCount": eventData.length,
|
||||
"historyDataCount": historyData.length
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,13 +419,13 @@ function getObjectData(prefix, colDefinitions, pluginObj) {
|
||||
}
|
||||
|
||||
function getHistoryData(prefix, colDefinitions, pluginObj) {
|
||||
|
||||
|
||||
return pluginHistory
|
||||
.filter(history => history.Plugin === prefix && shouldBeShown(history, pluginObj)) // First, filter based on the plugin prefix
|
||||
.sort((a, b) => b.Index - a.Index) // Then, sort by the Index field in descending order
|
||||
.slice(0, 50) // Limit the result to the first 50 entries
|
||||
.map(object =>
|
||||
colDefinitions.map(colDef =>
|
||||
.map(object =>
|
||||
colDefinitions.map(colDef =>
|
||||
getFormControl(colDef, object[colDef.column], object["Index"], colDefinitions, object)
|
||||
)
|
||||
);
|
||||
@@ -437,7 +453,7 @@ function generateTabNavigation(prefix, objectCount, eventCount, historyCount) {
|
||||
function generateDataTable(prefix, tableType, data, colDefinitions) {
|
||||
// Generate HTML for a DataTable and associated buttons for a given table type
|
||||
const headersHtml = colDefinitions.map(colDef => `<th class="${colDef.css_classes}">${getString(`${prefix}_${colDef.column}_name`)}</th>`).join('');
|
||||
|
||||
|
||||
return `
|
||||
<div id="${tableType.toLowerCase()}Target_${prefix}" class="tab-pane ${tableType == "Objects" ? "active":""}">
|
||||
<table id="${tableType.toLowerCase()}Table_${prefix}" class="display table table-striped table-stretched" data-my-dbtable="Plugins_${tableType}">
|
||||
@@ -485,43 +501,43 @@ function initializeDataTables(prefix, objectData, eventData, historyData, colDef
|
||||
// --------------------------------------------------------
|
||||
// Filter method that determines if an entry should be shown
|
||||
function shouldBeShown(entry, pluginObj)
|
||||
{
|
||||
{
|
||||
if (pluginObj.hasOwnProperty('data_filters')) {
|
||||
|
||||
|
||||
let dataFilters = pluginObj.data_filters;
|
||||
|
||||
// Loop through 'data_filters' array and appply filters on individual plugin entries
|
||||
for (let i = 0; i < dataFilters.length; i++) {
|
||||
|
||||
|
||||
compare_field_id = dataFilters[i].compare_field_id;
|
||||
compare_column = dataFilters[i].compare_column;
|
||||
compare_operator = dataFilters[i].compare_operator;
|
||||
compare_js_template = dataFilters[i].compare_js_template;
|
||||
compare_use_quotes = dataFilters[i].compare_use_quotes;
|
||||
compare_field_id_value = $(`#${compare_field_id}`).val();
|
||||
|
||||
|
||||
// console.log(compare_field_id_value);
|
||||
// console.log(compare_field_id);
|
||||
|
||||
|
||||
|
||||
// apply filter if the filter field has a valid value
|
||||
if(compare_field_id_value != undefined && compare_field_id_value != '--')
|
||||
if(compare_field_id_value != undefined && compare_field_id_value != '--')
|
||||
{
|
||||
// valid value
|
||||
// resolve the left and right part of the comparison
|
||||
// valid value
|
||||
// resolve the left and right part of the comparison
|
||||
let left = compare_js_template.replace('{value}', `${compare_field_id_value}`)
|
||||
let right = compare_js_template.replace('{value}', `${entry[compare_column]}`)
|
||||
|
||||
// include wrapper quotes if specified
|
||||
compare_use_quotes ? quotes = '"' : quotes = ''
|
||||
compare_use_quotes ? quotes = '"' : quotes = ''
|
||||
|
||||
result = eval(
|
||||
quotes + `${eval(left)}` + quotes +
|
||||
` ${compare_operator} ` +
|
||||
quotes + `${eval(right)}` + quotes
|
||||
);
|
||||
quotes + `${eval(left)}` + quotes +
|
||||
` ${compare_operator} ` +
|
||||
quotes + `${eval(right)}` + quotes
|
||||
);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,14 +561,28 @@ function purgeAll(callback) {
|
||||
|
||||
// --------------------------------------------------------
|
||||
function purgeAllExecute() {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/delete`;
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/dbHelper.php",
|
||||
data: { action: "delete", dbtable: dbTable, columnName: 'Plugin', id:plugPrefix },
|
||||
success: function(data, textStatus) {
|
||||
showModalOk ('Result', data );
|
||||
url: url,
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({
|
||||
dbtable: dbTable,
|
||||
columnName: 'Plugin',
|
||||
id: plugPrefix
|
||||
}),
|
||||
contentType: "application/json",
|
||||
success: function(response, textStatus) {
|
||||
showModalOk('Result', response.success ? "Deleted successfully" : (response.error || "Unknown error"));
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting:", status, error);
|
||||
showModalOk('Result', "Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -578,15 +608,29 @@ function deleteListed(plugPrefixArg, dbTableArg) {
|
||||
|
||||
// --------------------------------------------------------
|
||||
function deleteListedExecute() {
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/dbquery/delete`;
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "php/server/dbHelper.php",
|
||||
data: { action: "delete", dbtable: dbTable, columnName: 'Index', id:idArr.toString() },
|
||||
success: function(data, textStatus) {
|
||||
url: url,
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({
|
||||
dbtable: dbTable,
|
||||
columnName: 'Index',
|
||||
id: idArr.toString()
|
||||
}),
|
||||
contentType: "application/json",
|
||||
success: function(response, textStatus) {
|
||||
updateApi("plugins_objects")
|
||||
showModalOk('Result', data);
|
||||
showModalOk('Result', response.success ? "Deleted successfully" : (response.error || "Unknown error"));
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error deleting:", status, error);
|
||||
showModalOk('Result', "Error: " + (xhr.responseJSON?.error || error));
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -607,7 +651,7 @@ if (!$('.plugin-content:visible').length) {
|
||||
updater();
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
initFields();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ require 'php/templates/header.php';
|
||||
<script src="lib/iCheck/icheck.min.js"></script>
|
||||
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
|
||||
|
||||
<script>
|
||||
showSpinner();
|
||||
</script>
|
||||
@@ -34,19 +34,19 @@ require 'php/templates/header.php';
|
||||
<tbody>
|
||||
<!-- Data will be inserted here by DataTables -->
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
<div class="notification-buttons">
|
||||
<button id="clearNotificationsBtn" class="btn btn-danger"><?= lang("Gen_DeleteAll");?></button>
|
||||
<button id="notificationsMarkAllRead" class="btn btn-default"><?= lang("Notifications_Mark_All_Read");?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ require 'php/templates/header.php';
|
||||
"pageLength": parseInt(getSetting("UI_DEFAULT_PAGE_SIZE")),
|
||||
'lengthMenu' : getLengthMenu(parseInt(getSetting("UI_DEFAULT_PAGE_SIZE"))),
|
||||
"columns": [
|
||||
{ "data": "timestamp" ,
|
||||
{ "data": "timestamp" ,
|
||||
"render": function(data, type, row) {
|
||||
|
||||
var result = data.toString(); // Convert to string
|
||||
@@ -89,25 +89,25 @@ require 'php/templates/header.php';
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"data": "level",
|
||||
"render": function(data, type, row) {
|
||||
|
||||
|
||||
|
||||
switch (data) {
|
||||
case "info":
|
||||
color = 'green'
|
||||
color = 'green'
|
||||
break;
|
||||
|
||||
|
||||
case "alert":
|
||||
color = 'yellow'
|
||||
color = 'yellow'
|
||||
break;
|
||||
|
||||
case "interrupt":
|
||||
color = 'red'
|
||||
color = 'red'
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
color = 'red'
|
||||
break;
|
||||
@@ -122,13 +122,13 @@ require 'php/templates/header.php';
|
||||
var guid = data.split(":")[1].trim();
|
||||
return `<a href="report.php?guid=${guid}">Go to Report</a>`;
|
||||
} else {
|
||||
// clear quotes (") if wrapped in them
|
||||
// clear quotes (") if wrapped in them
|
||||
return (data.startsWith('"') && data.endsWith('"')) ? data.slice(1, -1) : data;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{ "data": "guid",
|
||||
|
||||
{ "data": "guid",
|
||||
"render": function(data, type, row) {
|
||||
return `<button class="copy-btn btn btn-info btn-flat" data-text="${data}" title="copy" onclick="copyToClipboard(this)">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
@@ -137,7 +137,7 @@ require 'php/templates/header.php';
|
||||
},
|
||||
{ "data": "read",
|
||||
"render": function(data, type, row) {
|
||||
if (data == 0) {
|
||||
if (data == 0) {
|
||||
return `<button class="mark-read-btn btn btn-info btn-flat" onclick="markNotificationAsRead('${row.guid}', this)">
|
||||
Mark as Read
|
||||
</button>`;
|
||||
@@ -145,7 +145,7 @@ require 'php/templates/header.php';
|
||||
return `<i class="fa-solid fa-check"></i>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
{
|
||||
targets: -1, // Target the last column
|
||||
@@ -162,7 +162,7 @@ require 'php/templates/header.php';
|
||||
{ "width": "5%", "targets": [1,3] }, // Set width of the first four columns to 10%
|
||||
{ "width": "50%", "targets": [2] }, // Set width of the first four columns to 10%
|
||||
{ "width": "5%", "targets": [4,5] }, // Set width of the "Content" column to 60%
|
||||
|
||||
|
||||
],
|
||||
"order": [[0, "desc"]]
|
||||
,
|
||||
@@ -175,16 +175,15 @@ require 'php/templates/header.php';
|
||||
});
|
||||
|
||||
|
||||
const phpEndpoint = 'php/server/utilNotification.php';
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
|
||||
// Function to clear all notifications
|
||||
$('#clearNotificationsBtn').click(function() {
|
||||
$.ajax({
|
||||
url: phpEndpoint,
|
||||
type: 'GET',
|
||||
data: {
|
||||
action: 'notifications_clear'
|
||||
},
|
||||
url: `${apiBase}/messaging/in-app/delete`,
|
||||
type: 'DELETE',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
// Clear the table and reload data
|
||||
window.location.reload()
|
||||
@@ -196,28 +195,26 @@ require 'php/templates/header.php';
|
||||
});
|
||||
});
|
||||
|
||||
// Function to clear all notifications
|
||||
// Function to mark all notifications as read
|
||||
$('#notificationsMarkAllRead').click(function() {
|
||||
$.ajax({
|
||||
url: phpEndpoint,
|
||||
type: 'GET',
|
||||
data: {
|
||||
action: 'notifications_mark_all_read'
|
||||
},
|
||||
url: `${apiBase}/messaging/in-app/read/all`,
|
||||
type: 'POST',
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function(response) {
|
||||
// Clear the table and reload data
|
||||
window.location.reload()
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.log("An error occurred while clearing notifications: " + error);
|
||||
console.log("An error occurred while marking notifications as read: " + error);
|
||||
// You can display an error message here if needed
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
|
||||
Reference in New Issue
Block a user