FE: refactor apiBase

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2026-01-10 08:46:16 +11:00
parent 49a075ca9d
commit 07277985b1
10 changed files with 76 additions and 92 deletions

View File

@@ -9,7 +9,6 @@ Check the the HTTP response of the failing backend call by following these steps
- Copy the URL causing the error and enter it in the address bar of your browser directly and hit enter. The copied URLs could look something like this (notice the query strings at the end):
- `http://<server>:20211/api/table_devices.json?nocache=1704141103121`
- `http://<server>:20211/php/server/devices.php?action=getDevicesTotals`
- Post the error response in the existing issue thread on GitHub or create a new issue and include the redacted response of the failing query.

View File

@@ -418,8 +418,8 @@ async function renderSmallBoxes() {
// Get data from the server
const apiToken = getSetting("API_TOKEN");
const apiBase = getApiBase();
const url = `${apiBase}/device/${getMac()}?period=${encodeURIComponent(period)}`;
const apiBaseUrl = getApiBase();
const url = `${apiBaseUrl}/device/${getMac()}?period=${encodeURIComponent(period)}`;
const response = await fetch(url, {
method: "GET",

View File

@@ -46,8 +46,8 @@ function getDeviceData() {
const apiToken = getSetting("API_TOKEN");
let period = $("#period").val()
const apiBase = getApiBase();
const url = `${apiBase}/device/${mac}?period=${encodeURIComponent(period)}`;
const apiBaseUrl = getApiBase();
const url = `${apiBaseUrl}/device/${mac}?period=${encodeURIComponent(period)}`;
// get data from server
$.ajax({
@@ -89,7 +89,7 @@ function getDeviceData() {
]
};
const graphQlUrl = `${apiBase}/graphql`;
const graphQlUrl = `${apiBaseUrl}/graphql`;
$.ajax({
url: graphQlUrl,
@@ -354,7 +354,7 @@ function setDeviceData(direction = '', refreshCallback = '') {
showSpinner();
const apiToken = getSetting("API_TOKEN"); // dynamic token
const apiBase = getApiBase();
const apiBaseUrl = getApiBase();
mac = $('#NEWDEV_devMac').val();
@@ -402,7 +402,7 @@ function setDeviceData(direction = '', refreshCallback = '') {
$.ajax({
url: `${apiBase}/device/${encodeURIComponent(mac)}`,
url: `${apiBaseUrl}/device/${encodeURIComponent(mac)}`,
type: "POST",
headers: {
"Authorization": "Bearer " + apiToken,

View File

@@ -50,8 +50,8 @@ function loadEventsData() {
const apiToken = getSetting("API_TOKEN");
const apiBase = getApiBase();
const url = `${apiBase}/dbquery/read`;
const apiBaseUrl = getApiBase();
const url = `${apiBaseUrl}/dbquery/read`;
$.ajax({
url: url,

View File

@@ -38,8 +38,8 @@
function loadPresenceData() {
const apiToken = getSetting("API_TOKEN");
const apiBase = getApiBase();
const url = `${apiBase}/sessions/calendar`;
const apiBaseUrl = getApiBase();
const url = `${apiBaseUrl}/sessions/calendar`;
$('#calendar').fullCalendar('removeEventSources');

View File

@@ -105,8 +105,8 @@ function loadSessionsData() {
// Build API base
const apiToken = getSetting("API_TOKEN");
const apiBase = getApiBase();
const url = `${apiBase}/sessions/${getMac()}?period=${encodeURIComponent(period)}`;
const apiBaseUrl = getApiBase();
const url = `${apiBaseUrl}/sessions/${getMac()}?period=${encodeURIComponent(period)}`;
// Call API with Authorization header
$.ajax({

View File

@@ -211,22 +211,16 @@
<script>
const protocol = window.location.protocol;
const host = window.location.hostname;
const port = getSetting("GRAPHQL_PORT");
const apiToken = getSetting("API_TOKEN");
const apiToken = getSetting("API_TOKEN");
const apiBaseUrl = getApiBase();
// ----------------------------------------------------------------
function manualnmapscan(targetip, mode) {
$("#scanoutput").empty();
const baseUrl = getApiBase();
$.ajax({
method: "POST",
url: `${baseUrl}/nettools/nmap`,
url: `${apiBaseUrl}/nettools/nmap`,
contentType: "application/json",
dataType: "json",
data: JSON.stringify({
@@ -265,7 +259,7 @@
$.ajax({
method: "GET",
url: `${protocol}//${host}:${port}/nettools/speedtest`,
url: `${apiBaseUrl}/nettools/speedtest`,
headers: {
"Authorization": "Bearer " + apiToken,
"Content-Type": "application/json"
@@ -316,7 +310,7 @@
$.ajax({
method: "POST",
url: `${protocol}//${host}:${port}/nettools/traceroute`,
url: `${apiBaseUrl}/nettools/traceroute`,
headers: {
"Authorization": "Bearer " + apiToken,
"Content-Type": "application/json"
@@ -362,11 +356,9 @@
$("#nslookupoutput").empty();
$.ajax({
method: "POST",
url: `${protocol}//${host}:${port}/nettools/nslookup`,
url: `${apiBaseUrl}/nettools/nslookup`,
headers: {
"Authorization": "Bearer " + apiToken,
"Content-Type": "application/json"
@@ -450,7 +442,7 @@
$.ajax({
method: "POST",
url: `${protocol}//${host}:${port}/nettools/wakeonlan`,
url: `${apiBaseUrl}/nettools/wakeonlan`,
headers: {
"Authorization": "Bearer " + apiToken,
"Content-Type": "application/json"
@@ -492,7 +484,7 @@
$.ajax({
method: "POST",
url: `${protocol}//${host}:${port}/device/copy`,
url: `${apiBaseUrl}/device/copy`,
headers: {
"Authorization": "Bearer " + apiToken,
"Content-Type": "application/json"
@@ -585,18 +577,14 @@
return;
}
const protocol = window.location.protocol; // "http:" or "https:"
const host = window.location.hostname; // current hostname
const port = getSetting("GRAPHQL_PORT"); // your dynamic port
const apiToken = getSetting("API_TOKEN"); // optional token if needed
// Build base URL dynamically
const baseUrl = getApiBase();
// Delete device events
$.ajax({
method: "DELETE",
url: `${baseUrl}/device/${encodeURIComponent(mac)}/events/delete`,
url: `${apiBaseUrl}/device/${encodeURIComponent(mac)}/events/delete`,
headers: {
"Authorization": "Bearer " + apiToken
},
@@ -641,11 +629,9 @@
return;
}
const baseUrl = getApiBase();
$.ajax({
method: "POST",
url: `${baseUrl}/device/${encodeURIComponent(mac)}/reset-props`,
url: `${apiBaseUrl}/device/${encodeURIComponent(mac)}/reset-props`,
dataType: "json",
headers: {
"Authorization": "Bearer " + apiToken
@@ -675,7 +661,7 @@
$.ajax({
method: "GET",
url: `${protocol}//${host}:${port}/nettools/internetinfo`,
url: `${apiBaseUrl}/nettools/internetinfo`,
headers: {
"Authorization": "Bearer " + apiToken,
"Content-Type": "application/json"

View File

@@ -44,7 +44,6 @@
case 'ExportCSV': ExportCSV(); break; // equivalent: export_devices
case 'ImportCSV': ImportCSV(); break; // equivalent: import_csv
case 'getDevicesTotals': getDevicesTotals(); break; // equivalent: devices_totals
case 'getDevicesListCalendar': getDevicesListCalendar(); break; // equivalent: devices_by_status
case 'updateNetworkLeaf': updateNetworkLeaf(); break; // equivalent: update_device_column(mac, column_name, column_value)
@@ -338,41 +337,6 @@ function ImportCSV() {
}
//------------------------------------------------------------------------------
// Query total numbers of Devices by status
//------------------------------------------------------------------------------
function getDevicesTotals() {
$resultJSON = "";
if(getCache("getDevicesTotals") != "")
{
$resultJSON = getCache("getDevicesTotals");
} else
{
global $db;
// combined query
$result = $db->query(
'SELECT
(SELECT COUNT(*) FROM Devices '. getDeviceCondition ('my').') as devices,
(SELECT COUNT(*) FROM Devices '. getDeviceCondition ('connected').') as connected,
(SELECT COUNT(*) FROM Devices '. getDeviceCondition ('favorites').') as favorites,
(SELECT COUNT(*) FROM Devices '. getDeviceCondition ('new').') as new,
(SELECT COUNT(*) FROM Devices '. getDeviceCondition ('down').') as down,
(SELECT COUNT(*) FROM Devices '. getDeviceCondition ('archived').') as archived
');
$row = $result -> fetchArray (SQLITE3_NUM);
$resultJSON = json_encode (array ($row[0], $row[1], $row[2], $row[3], $row[4], $row[5]));
// save to cache
setCache("getDevicesTotals", $resultJSON );
}
echo ($resultJSON);
}
//------------------------------------------------------------------------------
// Determine if Random MAC
//------------------------------------------------------------------------------

View File

@@ -567,7 +567,7 @@ def publish_notifications(db, mqtt_client):
try:
payload = json.loads(payload_str) # Deserialize JSON string
except Exception as e:
mylog('minimal', [f"[{pluginName}] ⚠ ERROR decoding JSON for notification GUID {notification["GUID"]}: {e}"])
mylog('minimal', [f"[{pluginName}] ⚠ ERROR decoding JSON for notification GUID {notification['GUID']}: {e}"])
continue # skip this notification
else:
# fallback generic payload (like webhook does)

View File

@@ -352,27 +352,62 @@ function initializeCalendar () {
// -----------------------------------------------------------------------------
/**
* Fetch device totals from the API and update dashboard counters.
*
* This function:
* - Stops the automatic refresh timer
* - Calls the `/devices/totals` API endpoint using Bearer token authentication
* - Updates the device summary boxes (all, connected, favorites, new, down, archived)
* - Restarts the refresh timer after completion
*
* Expected API response format:
* [
* devices, // Total devices
* connected, // Currently connected devices
* favorites, // Favorite devices
* new, // Newly discovered devices
* down, // Devices marked as down
* archived // Archived / hidden devices
* ]
*/
function getDevicesTotals () {
// stop timer
stopTimerRefreshData();
// get totals and put in boxes
$.get('php/server/devices.php?action=getDevicesTotals', function(data) {
var totalsDevices = JSON.parse(data);
const apiToken = getSetting("API_TOKEN");
const apiBaseUrl = getApiBase();
const totalsUrl = `${apiBaseUrl}/devices/totals`;
$('#devicesAll').html (totalsDevices[0].toLocaleString());
$('#devicesConnected').html (totalsDevices[1].toLocaleString());
$('#devicesFavorites').html (totalsDevices[2].toLocaleString());
$('#devicesNew').html (totalsDevices[3].toLocaleString());
$('#devicesDown').html (totalsDevices[4].toLocaleString());
$('#devicesHidden').html (totalsDevices[5].toLocaleString());
$.ajax({
url: totalsUrl,
method: "GET",
headers: {
"Authorization": `Bearer ${apiToken}`
},
success: function (totalsDevices) {
// Timer for refresh data
newTimerRefreshData (getDevicesTotals);
} );
$('#devicesAll').html (totalsDevices[0].toLocaleString());
$('#devicesConnected').html (totalsDevices[1].toLocaleString());
$('#devicesFavorites').html (totalsDevices[2].toLocaleString());
$('#devicesNew').html (totalsDevices[3].toLocaleString());
$('#devicesDown').html (totalsDevices[4].toLocaleString());
$('#devicesHidden').html (totalsDevices[5].toLocaleString());
// Timer for refresh data
newTimerRefreshData(getDevicesTotals);
},
error: function (xhr) {
console.error("Failed to load device totals:", xhr.responseText);
// Ensure refresh loop continues even on failure
newTimerRefreshData(getDevicesTotals);
}
});
}
// -----------------------------------------------------------------------------
function getDevicesPresence (status) {
// Save status selected
@@ -423,12 +458,12 @@ function getDevicesPresence (status) {
const apiToken = getSetting("API_TOKEN");
const apiBase = getApiBase();
const apiBaseUrl = getApiBase();
// -----------------------------
// Load Devices as Resources
// -----------------------------
const devicesUrl = `${apiBase}/devices/by-status?status=${deviceStatus}`;
const devicesUrl = `${apiBaseUrl}/devices/by-status?status=${deviceStatus}`;
$.ajax({
url: devicesUrl,
@@ -451,7 +486,7 @@ function getDevicesPresence (status) {
// -----------------------------
// Load Events
// -----------------------------
const eventsUrl = `${apiBase}/sessions/calendar?start=${startDate}&end=${endDate}`;
const eventsUrl = `${apiBaseUrl}/sessions/calendar?start=${startDate}&end=${endDate}`;
$('#calendar').fullCalendar('removeEventSources');
$('#calendar').fullCalendar('addEventSource', {