Skip to content

Commit f1a081d

Browse files
authored
Merge pull request #1685 from netalertx/next_release
Next release
2 parents 4abfbf6 + 39024d3 commit f1a081d

7 files changed

Lines changed: 116 additions & 12 deletions

File tree

front/php/server/util.php

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,72 @@ function saveSettings()
166166
copy($fullConfPath, $fullConfPath . ".bak");
167167
}
168168

169+
// Detect whether the frontend needs to block-wait for backend reload
170+
$requiresReloadWait = getReloadWaitRequired($decodedSettings);
171+
169172
// Open the file for writing without changing permissions
170173
$file = fopen($fullConfPath, "w") or die("Unable to open file!");
171174
fwrite($file, $txt);
172175
fclose($file);
173176

174-
echo "OK";
177+
echo json_encode(['success' => true, 'requiresReloadWait' => $requiresReloadWait]);
178+
179+
}
180+
181+
// -------------------------------------------------------------------------------------------
182+
// Determines if the frontend must wait (block) for the backend to finish reloading after a
183+
// settings save. Blocking is required when LOADED_PLUGINS changes or UI_WAIT_FOR_SETTINGS
184+
// is explicitly enabled. Defaults to true (safe) on any parsing error.
185+
function getReloadWaitRequired($decodedSettings) {
186+
$newLoadedPlugins = null;
187+
$uiWaitForSettings = false;
188+
189+
foreach ($decodedSettings as $setting) {
190+
if ($setting[1] === 'LOADED_PLUGINS') {
191+
$newLoadedPlugins = $setting[3];
192+
}
193+
if ($setting[1] === 'UI_WAIT_FOR_SETTINGS') {
194+
$uiWaitForSettings = ($setting[3] === true || $setting[3] === 1
195+
|| strtolower((string)$setting[3]) === 'true');
196+
}
197+
}
198+
199+
if ($uiWaitForSettings) {
200+
return true;
201+
}
202+
203+
$oldLoadedPlugins = getSettingValue('LOADED_PLUGINS');
204+
205+
// If the old value couldn't be read, default to blocking (safe).
206+
if (strpos((string)$oldLoadedPlugins, 'Could not') !== false) {
207+
return true;
208+
}
209+
210+
return normalizePluginList($oldLoadedPlugins) !== normalizePluginList($newLoadedPlugins);
211+
}
175212

213+
// -------------------------------------------------------------------------------------------
214+
// Normalise a plugin list value (PHP array, JSON array, or Python-style list) to a sorted
215+
// JSON string for reliable equality comparison.
216+
function normalizePluginList($value) {
217+
if ($value === null || $value === '') {
218+
return '[]';
219+
}
220+
if (is_array($value)) {
221+
$arr = $value;
222+
} else {
223+
$arr = json_decode($value, true);
224+
if (!is_array($arr)) {
225+
// Handle Python-style single-quoted lists: ['A','B']
226+
$jsonStr = str_replace("'", '"', (string)$value);
227+
$arr = json_decode($jsonStr, true);
228+
}
229+
if (!is_array($arr)) {
230+
return trim((string)$value);
231+
}
232+
}
233+
sort($arr);
234+
return json_encode($arr);
176235
}
177236

178237
// -------------------------------------------------------------------------------------------

front/php/templates/language/en_us.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@
807807
"settings_publishers_label": "Publishers",
808808
"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>",
809809
"settings_saved": "<br/>Settings saved. <br/> Reloading… <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
810+
"settings_saved_background": "Settings saved. Changes are being applied in the background.",
810811
"settings_system_icon": "fa-solid fa-gear",
811812
"settings_system_label": "System",
812813
"settings_update_item_warning": "Update the value below. Be careful to follow the previous format. <b>Validation is not performed.</b>",

front/plugins/avahi_scan/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"display_name": [
2020
{
2121
"language_code": "en_us",
22-
"string": "AVAHISCAN (Name discovery)"
22+
"string": "AVAHISCAN (Naming)"
2323
}
2424
],
2525
"icon": [

front/plugins/nbtscan_scan/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"display_name": [
2020
{
2121
"language_code": "en_us",
22-
"string": "NBTSCAN (Name discovery)"
22+
"string": "NBTSCAN (Naming)"
2323
}
2424
],
2525
"icon": [

front/plugins/nslookup_scan/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"display_name": [
2020
{
2121
"language_code": "en_us",
22-
"string": "NSLOOKUP (Name discovery)"
22+
"string": "NSLOOKUP (Naming)"
2323
}
2424
],
2525
"icon": [

front/plugins/ui_settings/config.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,13 @@
264264
"localized": [],
265265
"name": [
266266
{
267+
"language_code": "en_us",
267268
"string": "Default page size"
268269
}
269270
],
270271
"description": [
271272
{
273+
"language_code": "en_us",
272274
"string": "Default number of items shown in tables per page, for example in teh Devices lists."
273275
}
274276
]
@@ -704,6 +706,34 @@
704706
"string": "Based on which value should the network topology view be ordered."
705707
}
706708
]
709+
},
710+
{
711+
"function": "WAIT_FOR_SETTINGS",
712+
"type": {
713+
"dataType": "boolean",
714+
"elements": [
715+
{
716+
"elementType": "input",
717+
"elementOptions": [{ "type": "checkbox" }],
718+
"transformers": []
719+
}
720+
]
721+
},
722+
"default_value": false,
723+
"options": [],
724+
"localized": ["name", "description"],
725+
"name": [
726+
{
727+
"language_code": "en_us",
728+
"string": "Wait for settings reload"
729+
}
730+
],
731+
"description": [
732+
{
733+
"language_code": "en_us",
734+
"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."
735+
}
736+
]
707737
}
708738
]
709739
}

front/settings.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -615,19 +615,33 @@ function: 'savesettings',
615615
settings: JSON.stringify(settingsArray) },
616616
success: function(data, textStatus) {
617617

618-
if(data == "OK")
619-
{
620-
// showMessage (getString("settings_saved"), 5000, "modal_grey");
618+
// Parse response: support both legacy "OK" string and new JSON format
619+
let saveSucceeded = false;
620+
let requiresReloadWait = true; // safe default
621+
622+
if (data === "OK") {
623+
saveSucceeded = true;
624+
} else {
625+
let parsed = null;
626+
try { parsed = (typeof data === 'object') ? data : JSON.parse(data); } catch(e) {}
627+
if (parsed && parsed.success === true) {
628+
saveSucceeded = true;
629+
requiresReloadWait = parsed.requiresReloadWait === true;
630+
}
631+
}
632+
633+
if (saveSucceeded) {
621634
// Remove navigation prompt "Are you sure you want to leave..."
622635
window.onbeforeunload = null;
623636

624-
// Reloads the current page
625-
// setTimeout("clearCache()", 5000);
626-
627637
write_notification(`[Settings] Settings saved by the user`, 'info')
628638

629-
clearCache()
630-
} else{
639+
if (requiresReloadWait) {
640+
clearCache()
641+
} else {
642+
showMessage(getString("settings_saved_background"), 5000, "modal_green");
643+
}
644+
} else {
631645
// something went wrong
632646
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')
633647
write_notification(data, 'interrupt')

0 commit comments

Comments
 (0)