mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-06-20 22:30:11 -04:00
@@ -166,15 +166,74 @@ function saveSettings()
|
||||
copy($fullConfPath, $fullConfPath . ".bak");
|
||||
}
|
||||
|
||||
// Detect whether the frontend needs to block-wait for backend reload
|
||||
$requiresReloadWait = getReloadWaitRequired($decodedSettings);
|
||||
|
||||
// Open the file for writing without changing permissions
|
||||
$file = fopen($fullConfPath, "w") or die("Unable to open file!");
|
||||
fwrite($file, $txt);
|
||||
fclose($file);
|
||||
|
||||
echo "OK";
|
||||
echo json_encode(['success' => true, 'requiresReloadWait' => $requiresReloadWait]);
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Determines if the frontend must wait (block) for the backend to finish reloading after a
|
||||
// settings save. Blocking is required when LOADED_PLUGINS changes or UI_WAIT_FOR_SETTINGS
|
||||
// is explicitly enabled. Defaults to true (safe) on any parsing error.
|
||||
function getReloadWaitRequired($decodedSettings) {
|
||||
$newLoadedPlugins = null;
|
||||
$uiWaitForSettings = false;
|
||||
|
||||
foreach ($decodedSettings as $setting) {
|
||||
if ($setting[1] === 'LOADED_PLUGINS') {
|
||||
$newLoadedPlugins = $setting[3];
|
||||
}
|
||||
if ($setting[1] === 'UI_WAIT_FOR_SETTINGS') {
|
||||
$uiWaitForSettings = ($setting[3] === true || $setting[3] === 1
|
||||
|| strtolower((string)$setting[3]) === 'true');
|
||||
}
|
||||
}
|
||||
|
||||
if ($uiWaitForSettings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$oldLoadedPlugins = getSettingValue('LOADED_PLUGINS');
|
||||
|
||||
// If the old value couldn't be read, default to blocking (safe).
|
||||
if (strpos((string)$oldLoadedPlugins, 'Could not') !== false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return normalizePluginList($oldLoadedPlugins) !== normalizePluginList($newLoadedPlugins);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Normalise a plugin list value (PHP array, JSON array, or Python-style list) to a sorted
|
||||
// JSON string for reliable equality comparison.
|
||||
function normalizePluginList($value) {
|
||||
if ($value === null || $value === '') {
|
||||
return '[]';
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$arr = $value;
|
||||
} else {
|
||||
$arr = json_decode($value, true);
|
||||
if (!is_array($arr)) {
|
||||
// Handle Python-style single-quoted lists: ['A','B']
|
||||
$jsonStr = str_replace("'", '"', (string)$value);
|
||||
$arr = json_decode($jsonStr, true);
|
||||
}
|
||||
if (!is_array($arr)) {
|
||||
return trim((string)$value);
|
||||
}
|
||||
}
|
||||
sort($arr);
|
||||
return json_encode($arr);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// check server/api_server/api_server_start.py for equivalents
|
||||
|
||||
@@ -807,6 +807,7 @@
|
||||
"settings_publishers_label": "Publishers",
|
||||
"settings_readonly": "Can't READ or WRITE <code>app.conf</code>. Try restarting the container and read the <a href=\"https://docs.netalertx.com/FILE_PERMISSIONS\" target=\"_blank\">file permissions documentation</a>",
|
||||
"settings_saved": "<br/>Settings saved. <br/> Reloading… <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_saved_background": "Settings saved. Changes are being applied in the background.",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "System",
|
||||
"settings_update_item_warning": "Update the value below. Be careful to follow the previous format. <b>Validation is not performed.</b>",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "AVAHISCAN (Name discovery)"
|
||||
"string": "AVAHISCAN (Naming)"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "NBTSCAN (Name discovery)"
|
||||
"string": "NBTSCAN (Naming)"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "NSLOOKUP (Name discovery)"
|
||||
"string": "NSLOOKUP (Naming)"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
|
||||
@@ -264,11 +264,13 @@
|
||||
"localized": [],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Default page size"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Default number of items shown in tables per page, for example in teh Devices lists."
|
||||
}
|
||||
]
|
||||
@@ -704,6 +706,34 @@
|
||||
"string": "Based on which value should the network topology view be ordered."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "WAIT_FOR_SETTINGS",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Wait for settings reload"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When enabled, the UI blocks after saving settings until the backend finishes reloading. When disabled (default), the UI returns immediately for most changes and only waits when plugin configuration changes."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -615,19 +615,33 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
settings: JSON.stringify(settingsArray) },
|
||||
success: function(data, textStatus) {
|
||||
|
||||
if(data == "OK")
|
||||
{
|
||||
// showMessage (getString("settings_saved"), 5000, "modal_grey");
|
||||
// Parse response: support both legacy "OK" string and new JSON format
|
||||
let saveSucceeded = false;
|
||||
let requiresReloadWait = true; // safe default
|
||||
|
||||
if (data === "OK") {
|
||||
saveSucceeded = true;
|
||||
} else {
|
||||
let parsed = null;
|
||||
try { parsed = (typeof data === 'object') ? data : JSON.parse(data); } catch(e) {}
|
||||
if (parsed && parsed.success === true) {
|
||||
saveSucceeded = true;
|
||||
requiresReloadWait = parsed.requiresReloadWait === true;
|
||||
}
|
||||
}
|
||||
|
||||
if (saveSucceeded) {
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
|
||||
// Reloads the current page
|
||||
// setTimeout("clearCache()", 5000);
|
||||
|
||||
write_notification(`[Settings] Settings saved by the user`, 'info')
|
||||
|
||||
clearCache()
|
||||
} else{
|
||||
if (requiresReloadWait) {
|
||||
clearCache()
|
||||
} else {
|
||||
showMessage(getString("settings_saved_background"), 5000, "modal_green");
|
||||
}
|
||||
} else {
|
||||
// something went wrong
|
||||
write_notification("[Important] Please take a screenshot of the Console tab in the browser (F12) and next error. Submit it (with the nginx and php error logs) as a new issue here: https://github.com/netalertx/NetAlertX/issues", 'interrupt')
|
||||
write_notification(data, 'interrupt')
|
||||
|
||||
Reference in New Issue
Block a user