Loading spinner + app_state.json, settings work

This commit is contained in:
Jokob-sk
2023-09-16 21:14:34 +10:00
parent 40c6c65ee5
commit 44856f9c04
8 changed files with 117 additions and 52 deletions

View File

@@ -209,6 +209,8 @@
// -----------------------------------------------------------------------------
function main () {
handleLoadingDialog()
// get from cookie if available (need to use decodeURI as saved as part of URI in PHP)
cookieColumnsVisibleStr = decodeURI(getCookie("Front_Devices_Columns_Visible")).replaceAll('%2C',',')
@@ -542,6 +544,26 @@ function getDevicesList (status) {
'php/server/devices.php?action=getDevicesList&status=' + deviceStatus).load();
};
function handleLoadingDialog()
{
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
console.log(appState["showSpinner"])
if(appState["showSpinner"])
{
showSpinner("settings_old")
setTimeout("handleLoadingDialog()", 1000);
} else
{
hideSpinner()
}
})
}
</script>
<script src="js/pialert_common.js"></script>

View File

@@ -539,11 +539,12 @@ function isEmpty(value)
// -----------------------------------------------------------------------------
function showSpinner(stringKey='Loading')
{
if($("#loadingSpinner"))
if($("#loadingSpinner").length)
{
$("#loadingSpinner").show();
}
else{
else{
html = `
<!-- spinner -->
<div id="loadingSpinner" style="display: block">

View File

@@ -85,8 +85,6 @@ if ($ENABLED_DARKMODE === True) {
function updateState(){
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
// console.log(appState)
document.getElementById('state').innerHTML = appState["currentState"].replaceAll('"', '');
setTimeout("updateState()", 1000);
@@ -106,12 +104,6 @@ if ($ENABLED_DARKMODE === True) {
setTimeout("show_pia_servertime()", 1000);
}
// refresh page on focus - adds a lot of SQL queries overhead onto the DB - disabling for now
// document.addEventListener("visibilitychange",()=>{
// if(document.visibilityState==="visible"){
// window.location.href = window.location.href.split('#')[0];
// }
// })
</script>

View File

@@ -460,7 +460,7 @@
"Settings_Metadata_Toggle" : "Show/hide metadata for the given setting.",
"settings_missing" : "Not all settings loaded, refresh the page! This is probably caused by a high load on the database.",
"settings_missing_block" : "You can not save your settings without specifying all setting keys. Refresh the page. This is probably caused by a high load on the database.",
"settings_old" : "The settings in the DB (shown on this page) are outdated. This is probably caused by a running scan. The settings were saved in the <code>pialert.conf</code> file, but the background process didn not have time to import it yet to the DB. You can wait until the settings get refreshed so you do not overwrite your old values. Feel free to save your settings either way if you do not mind losing the settings between the last save and now. There are also backup files created if you need to compare your settings later.",
"settings_old" : "Importing settings and re-initializing...",
"settings_imported" : "Last time settings were imported from the pialert.conf file:",
"settings_expand_all" : "Expand all",
"Setting_Override" : "Override value",

View File

@@ -450,7 +450,7 @@
"Settings_Title" : "<i class=\"fa fa-cog\"> Configuración</i>",
"settings_missing" : "Actualiza la página, no todos los ajustes se han cargado. Probablemente sea por una sobrecarga de la base de datos.",
"settings_missing_block" : "No puedes guardar los ajustes sin establecer todas las claves. Actualiza la página. Problabmente esté causado por una sobrecarga de la base de datos.",
"settings_old" : "Los ajustes mostrados en esta página están desactualizados. Probablemente sea por un escaneo en proceso. Los ajustes se guardan en el archivo <code>pialert.conf</code>, pero el proceso en segundo plano no las ha importado todavía a la base de datos. Puedes esperar a que los ajustes se actualicen para evitar sobreescribirlos con los ajustes antiguos. Si te da igual perder los ajustes desde la última vez que guardaste y ahora, siéntete libre de guardarlos de nuevo. También hay copias de seguridad creadas si necesitas comparar tus ajustes más tarde.",
"settings_old" : "N/A",
"settings_imported" : "Última vez que los ajustes fueron importados desde el archivo pialert.conf:",
"settings_expand_all" : "Expandir todo",
"Setting_Override" : "Sobreescribir el valor",

View File

@@ -575,16 +575,24 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
showModalOk('WARNING', "<?= lang("settings_missing_block")?>");
} else
{
// trigger a save settings event in the backend
$.ajax({
method: "POST",
url: "php/server/util.php",
data: {
function: 'savesettings',
settings: JSON.stringify(collectSettings()) },
success: function(data, textStatus) {
success: function(data, textStatus) {
showModalOk ('Result', data );
// Remove navigation prompt "Are you sure you want to leave..."
window.onbeforeunload = null;
window.onbeforeunload = null;
// Reloads the current page
setTimeout("window.location.reload()", 3000);
}
});
@@ -607,25 +615,45 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
var result = data;
if(key == "Back_Settings_Imported")
{
fileModificationTime = <?php echo filemtime($confPath)*1000;?>;
importedMiliseconds = parseInt(result.match( /\d+/g ).join('')); // sanitize the string and get only the numbers
result = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" }); //.toDateString("");
// check if displayed settings are outdated
if(fileModificationTime > importedMiliseconds)
{
showModalOk('WARNING: Outdated settings displayed', "<?= lang("settings_old")?>");
}
} else{
result = result.replaceAll('"', '');
}
result = result.replaceAll('"', '');
document.getElementById(targetId).innerHTML = result.replaceAll('"', '');
});
}
// -----------------------------------------------------------------------------
function handleLoadingDialog()
{
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
fileModificationTime = <?php echo filemtime($confPath)*1000;?>;
console.log(appState["settingsImported"]*1000)
importedMiliseconds = parseInt((appState["settingsImported"]*1000));
humanReadable = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" });
console.log(humanReadable.replaceAll('"', ''))
// check if displayed settings are outdated
// if(fileModificationTime > importedMiliseconds)
if(appState["showSpinner"] || fileModificationTime > importedMiliseconds)
{
showSpinner("settings_old")
setTimeout("handleLoadingDialog()", 1000);
} else
{
hideSpinner()
}
document.getElementById('lastImportedTime').innerHTML = humanReadable;
})
}
// -----------------------------------------------------------------------------
@@ -722,6 +750,10 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
// ---------------------------------------------------------
// Show last time settings have been imported
getParam("lastImportedTime", "Back_Settings_Imported", skipCache = true);
// getParam("lastImportedTime", "Back_Settings_Imported", skipCache = true);
handleLoadingDialog()
</script>

View File

@@ -37,17 +37,37 @@ def timeNow():
#-------------------------------------------------------------------------------
# A class to manage the application state and to provide a frontend accessible API point
class app_state_class:
def __init__(self, currentState):
# json file containing the state to communicate with teh frontend
def __init__(self, currentState, settingsSaved=None, settingsImported=None, showSpinner=False):
# json file containing the state to communicate with the frontend
stateFile = apiPath + '/app_state.json'
# update self
# Update self
self.currentState = currentState
self.lastUpdated = str(timeNowTZ())
# update .json file
write_file(stateFile , json.dumps(self, cls=AppStateEncoder))
# Check if the file exists and init values
if os.path.exists(stateFile):
with open(stateFile, 'r') as json_file:
previousState = json.load(json_file)
self.settingsSaved = previousState.get("settingsSaved", 0)
self.settingsImported = previousState.get("settingsImported", 0)
self.showSpinner = previousState.get("showSpinner", False)
else:
self.settingsSaved = 0
self.settingsImported = 0
self.showSpinner = False
# Overwrite with provided parameters if not None
if settingsSaved is not None:
self.settingsSaved = settingsSaved
if settingsImported is not None:
self.settingsImported = settingsImported
if showSpinner is not None:
self.showSpinner = showSpinner
# Update .json file
with open(stateFile, 'w') as json_file:
json.dump(self, json_file, cls=AppStateEncoder, indent=4)
def isSet(self):
@@ -69,9 +89,9 @@ class AppStateEncoder(json.JSONEncoder):
return super().default(obj)
#-------------------------------------------------------------------------------
def updateState(newState):
def updateState(newState, settingsSaved = None, settingsImported = None, showSpinner = False):
state = app_state_class(newState)
state = app_state_class(newState, settingsSaved, settingsImported, showSpinner)
#-------------------------------------------------------------------------------
def updateSubnets(scan_subnets):

View File

@@ -74,7 +74,7 @@ def importConfigs (db):
return
# Header
updateState("Import config")
updateState("Import config", showSpinner = True)
mylog('debug', ['[Import Config] importing config file'])
conf.mySettings = [] # reset settings
@@ -170,15 +170,15 @@ def importConfigs (db):
#cron_instance = Cron()
# timestamps of last execution times
conf.startTime = conf.time_started
now_minus_24h = conf.time_started - datetime.timedelta(hours = 24)
conf.startTime = conf.time_started
now_minus_24h = conf.time_started - datetime.timedelta(hours = 24)
# set these times to the past to force the first run
conf.last_internet_IP_scan = now_minus_24h
conf.last_scan_run = now_minus_24h
conf.last_cleanup = now_minus_24h
conf.last_update_vendors = conf.time_started - datetime.timedelta(days = 6) # update vendors 24h after first run and then once a week
conf.last_version_check = now_minus_24h
conf.last_internet_IP_scan = now_minus_24h
conf.last_scan_run = now_minus_24h
conf.last_cleanup = now_minus_24h
conf.last_update_vendors = conf.time_started - datetime.timedelta(days = 6) # update vendors 24h after first run and then once a week
conf.last_version_check = now_minus_24h
# TODO cleanup later ----------------------------------------------------------------------------------
@@ -254,8 +254,6 @@ def importConfigs (db):
conf.plugins_once_run = False
# -----------------
# Plugins END
@@ -279,9 +277,9 @@ def importConfigs (db):
run_plugin_scripts(db, 'before_config_save' )
# Used to determine the next import
conf.lastImportedConfFile = os.path.getmtime(config_file)
#TO DO this creates a circular reference between API and HELPER !
conf.lastImportedConfFile = os.path.getmtime(config_file)
updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False)
mylog('minimal', '[Config] Imported new config')