mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
chore:Settings DB table refactor
This commit is contained in:
@@ -819,7 +819,7 @@ function initializeCombos () {
|
|||||||
initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false);
|
initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false);
|
||||||
|
|
||||||
// Initiate dropdown
|
// Initiate dropdown
|
||||||
// generateSetOptions(settingKey, // Identifier for the setting
|
// generateSetOptions(setKey, // Identifier for the setting
|
||||||
// valuesArray, // Array of values to be pre-selected in the dropdown
|
// valuesArray, // Array of values to be pre-selected in the dropdown
|
||||||
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||||
// callbackToGenerateEntries, // Callback function to generate entries based on options
|
// callbackToGenerateEntries, // Callback function to generate entries based on options
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require 'php/templates/header.php';
|
require 'php/templates/header.php';
|
||||||
require 'php/components/graph_online_history.php';
|
|
||||||
|
|
||||||
// check permissions
|
// check permissions
|
||||||
$dbPath = "../db/app.db";
|
$dbPath = "../db/app.db";
|
||||||
$confPath = "../config/app.conf";
|
$confPath = "../config/app.conf";
|
||||||
@@ -56,8 +54,10 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<script src="lib/AdminLTE/bower_components/chart.js/Chart.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
<script src="lib/AdminLTE/bower_components/chart.js/Chart.js?v=<?php include 'php/templates/version.php'; ?>"></script>
|
||||||
<!-- The online history chart is rendered here -->
|
<!-- presence chart -->
|
||||||
<canvas id="OnlineChart" style="width:100%; height: 150px; margin-bottom: 15px;"></canvas>
|
<?php
|
||||||
|
require 'php/components/graph_online_history.php';
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.box-body -->
|
<!-- /.box-body -->
|
||||||
@@ -195,16 +195,10 @@ function mapIndx(oldIndex)
|
|||||||
// Query total numbers of Devices by status
|
// Query total numbers of Devices by status
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
function getDevicesTotals() {
|
function getDevicesTotals() {
|
||||||
// Check cache first
|
|
||||||
let resultJSON = getCache("getDevicesTotals");
|
|
||||||
|
|
||||||
if (resultJSON !== "") {
|
|
||||||
resultJSON = JSON.parse(resultJSON);
|
|
||||||
processDeviceTotals(resultJSON);
|
|
||||||
} else {
|
|
||||||
// Fetch data via AJAX
|
// Fetch data via AJAX
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/table_devices_tiles.json",
|
url: '/api/table_devices_tiles.json?nocache=' + Date.now(),
|
||||||
type: "GET",
|
type: "GET",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
@@ -224,7 +218,7 @@ function getDevicesTotals() {
|
|||||||
console.error("Failed to fetch devices data:", error);
|
console.error("Failed to fetch devices data:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function processDeviceTotals(devicesData) {
|
function processDeviceTotals(devicesData) {
|
||||||
|
|||||||
@@ -124,19 +124,19 @@ function cacheSettings()
|
|||||||
|
|
||||||
settingsData.forEach((set) => {
|
settingsData.forEach((set) => {
|
||||||
|
|
||||||
resolvedOptions = createArray(set.Options)
|
resolvedOptions = createArray(set.setOptions)
|
||||||
resolvedOptionsOld = resolvedOptions
|
resolvedOptionsOld = resolvedOptions
|
||||||
setPlugObj = {};
|
setPlugObj = {};
|
||||||
options_params = [];
|
options_params = [];
|
||||||
resolved = ""
|
resolved = ""
|
||||||
|
|
||||||
// proceed only if first option item contains something to resolve
|
// proceed only if first option item contains something to resolve
|
||||||
if( !set.Code_Name.includes("__metadata") &&
|
if( !set.setKey.includes("__metadata") &&
|
||||||
resolvedOptions.length != 0 &&
|
resolvedOptions.length != 0 &&
|
||||||
resolvedOptions[0].includes("{value}"))
|
resolvedOptions[0].includes("{value}"))
|
||||||
{
|
{
|
||||||
// get setting definition from the plugin config if available
|
// get setting definition from the plugin config if available
|
||||||
setPlugObj = getPluginSettingObject(pluginsData, set.Code_Name)
|
setPlugObj = getPluginSettingObject(pluginsData, set.setKey)
|
||||||
|
|
||||||
// check if options contains parameters and resolve
|
// check if options contains parameters and resolve
|
||||||
if(setPlugObj != {} && setPlugObj["options_params"])
|
if(setPlugObj != {} && setPlugObj["options_params"])
|
||||||
@@ -161,8 +161,8 @@ function cacheSettings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCache(`pia_set_${set.Code_Name}`, set.Value)
|
setCache(`pia_set_${set.setKey}`, set.setValue)
|
||||||
setCache(`pia_set_opt_${set.Code_Name}`, resolvedOptions)
|
setCache(`pia_set_opt_${set.setKey}`, resolvedOptions)
|
||||||
});
|
});
|
||||||
}).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization
|
}).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization
|
||||||
})
|
})
|
||||||
@@ -1167,9 +1167,9 @@ function arraysContainSameValues(arr1, arr2) {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Hide elements on the page based on the supplied setting
|
// Hide elements on the page based on the supplied setting
|
||||||
function hideUIelements(settingKey) {
|
function hideUIelements(setKey) {
|
||||||
|
|
||||||
hiddenSectionsSetting = getSetting(settingKey)
|
hiddenSectionsSetting = getSetting(setKey)
|
||||||
|
|
||||||
if(hiddenSectionsSetting != "") // handle if settings not yet initialized
|
if(hiddenSectionsSetting != "") // handle if settings not yet initialized
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -215,14 +215,14 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const settingsCodeNames = settingsJSON_DB.map((setting) => setting.Code_Name);
|
const settingsCodeNames = settingsJSON_DB.map((setting) => setting.setKey);
|
||||||
const detailedCodeNames = settingsArray.map((item) => item[1]);
|
const detailedCodeNames = settingsArray.map((item) => item[1]);
|
||||||
|
|
||||||
const missingCodeNamesOnPage = detailedCodeNames.filter(
|
const missingCodeNamesOnPage = detailedCodeNames.filter(
|
||||||
(codeName) => !settingsCodeNames.includes(codeName)
|
(setKey) => !settingsCodeNames.includes(setKey)
|
||||||
);
|
);
|
||||||
const missingCodeNamesInDB = settingsCodeNames.filter(
|
const missingCodeNamesInDB = settingsCodeNames.filter(
|
||||||
(codeName) => !detailedCodeNames.includes(codeName)
|
(setKey) => !detailedCodeNames.includes(setKey)
|
||||||
);
|
);
|
||||||
|
|
||||||
// check if the number of settings on the page and in the DB are the same
|
// check if the number of settings on the page and in the DB are the same
|
||||||
@@ -453,11 +453,11 @@ function filterRows(inputText) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var description = $row.find(".setting_description").text().toLowerCase();
|
var description = $row.find(".setting_description").text().toLowerCase();
|
||||||
var codeName = $row.find(".setting_name code").text().toLowerCase();
|
var setKey = $row.find(".setting_name code").text().toLowerCase();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
description.includes(inputText.toLowerCase()) ||
|
description.includes(inputText.toLowerCase()) ||
|
||||||
codeName.includes(inputText.toLowerCase())
|
setKey.includes(inputText.toLowerCase())
|
||||||
) {
|
) {
|
||||||
$row.show();
|
$row.show();
|
||||||
anyVisible = true; // Set the flag to true if at least one row is visible
|
anyVisible = true; // Set the flag to true if at least one row is visible
|
||||||
@@ -554,7 +554,7 @@ function overrideToggle(element) {
|
|||||||
|
|
||||||
// Generate options or set options based on the provided parameters
|
// Generate options or set options based on the provided parameters
|
||||||
function generateOptionsOrSetOptions(
|
function generateOptionsOrSetOptions(
|
||||||
codeName,
|
setKey,
|
||||||
valuesArray, // Array of values to be pre-selected in the dropdown
|
valuesArray, // Array of values to be pre-selected in the dropdown
|
||||||
placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||||
processDataCallback, // Callback function to generate entries based on options
|
processDataCallback, // Callback function to generate entries based on options
|
||||||
@@ -562,10 +562,10 @@ function generateOptionsOrSetOptions(
|
|||||||
transformers = [] // Transformers to be applied to the values
|
transformers = [] // Transformers to be applied to the values
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// console.log(codeName);
|
// console.log(setKey);
|
||||||
|
|
||||||
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||||
options = arrayToObject(createArray(getSettingOptions(codeName)))
|
options = arrayToObject(createArray(getSettingOptions(setKey)))
|
||||||
|
|
||||||
// Call to render lists
|
// Call to render lists
|
||||||
renderList(
|
renderList(
|
||||||
@@ -638,7 +638,7 @@ function reverseTransformers(val, transformers) {
|
|||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// Function to initialize relevant variables based on HTML element
|
// Function to initialize relevant variables based on HTML element
|
||||||
const handleElementOptions = (codeName, elementOptions, transformers, val) => {
|
const handleElementOptions = (setKey, elementOptions, transformers, val) => {
|
||||||
let inputType = "text";
|
let inputType = "text";
|
||||||
let readOnly = "";
|
let readOnly = "";
|
||||||
let isMultiSelect = false;
|
let isMultiSelect = false;
|
||||||
@@ -687,7 +687,7 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => {
|
|||||||
}
|
}
|
||||||
if (option.sourceSuffixes) {
|
if (option.sourceSuffixes) {
|
||||||
$.each(option.sourceSuffixes, function (index, suf) {
|
$.each(option.sourceSuffixes, function (index, suf) {
|
||||||
sourceIds.push(codeName + suf);
|
sourceIds.push(setKey + suf);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (option.separator) {
|
if (option.separator) {
|
||||||
|
|||||||
@@ -923,10 +923,10 @@ var wysihtml5 = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function DOMException(codeName) {
|
function DOMException(settingKey) {
|
||||||
this.code = this[codeName];
|
this.code = this[settingKey];
|
||||||
this.codeName = codeName;
|
this.settingKey = settingKey;
|
||||||
this.message = "DOMException: " + this.codeName;
|
this.message = "DOMException: " + this.settingKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMException.prototype = {
|
DOMException.prototype = {
|
||||||
@@ -1343,9 +1343,9 @@ var wysihtml5 = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertNode(node, codeName) {
|
function assertNode(node, settingKey) {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
throw new DOMException(codeName);
|
throw new DOMException(settingKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -80,10 +80,10 @@
|
|||||||
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
||||||
|
|
||||||
const relevantColumns = settingsData.filter(set =>
|
const relevantColumns = settingsData.filter(set =>
|
||||||
set.Group === "NEWDEV" &&
|
set.setGroup === "NEWDEV" &&
|
||||||
set.Code_Name.includes("_dev") &&
|
set.setKey.includes("_dev") &&
|
||||||
!excludedColumns.includes(set.Code_Name) &&
|
!excludedColumns.includes(set.setKey) &&
|
||||||
!set.Code_Name.includes("__metadata")
|
!set.setKey.includes("__metadata")
|
||||||
);
|
);
|
||||||
|
|
||||||
const generateSimpleForm = columns => {
|
const generateSimpleForm = columns => {
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
// Append form groups to the column
|
// Append form groups to the column
|
||||||
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
|
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
|
||||||
|
|
||||||
const setTypeObject = JSON.parse(columns[j].Type.replace(/'/g, '"'));
|
const setTypeObject = JSON.parse(columns[j].setType.replace(/'/g, '"'));
|
||||||
|
|
||||||
// get the element with the input value(s)
|
// get the element with the input value(s)
|
||||||
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
||||||
@@ -137,31 +137,31 @@
|
|||||||
// render based on element type
|
// render based on element type
|
||||||
if (elementType === 'select') {
|
if (elementType === 'select') {
|
||||||
|
|
||||||
targetLocation = columns[j].Code_Name + "_generateSetOptions"
|
targetLocation = columns[j].setKey + "_generateSetOptions"
|
||||||
|
|
||||||
generateOptionsOrSetOptions(columns[j].Code_Name, [], targetLocation, generateOptions)
|
generateOptionsOrSetOptions(columns[j].setKey, [], targetLocation, generateOptions)
|
||||||
|
|
||||||
console.log(columns[j].Code_Name)
|
console.log(columns[j].setKey)
|
||||||
// Handle Icons as they need a preview
|
// Handle Icons as they need a preview
|
||||||
if(columns[j].Code_Name == 'NEWDEV_devIcon')
|
if(columns[j].setKey == 'NEWDEV_devIcon')
|
||||||
{
|
{
|
||||||
input = `
|
input = `
|
||||||
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
|
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
|
||||||
<select class="form-control"
|
<select class="form-control"
|
||||||
onChange="updateIconPreview(this)"
|
onChange="updateIconPreview(this)"
|
||||||
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
|
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
|
||||||
id="${columns[j].Code_Name}"
|
id="${columns[j].setKey}"
|
||||||
data-my-column="${columns[j].Code_Name}"
|
data-my-column="${columns[j].setKey}"
|
||||||
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" >
|
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
|
||||||
<option id="${targetLocation}"></option>
|
<option id="${targetLocation}"></option>
|
||||||
</select>`
|
</select>`
|
||||||
|
|
||||||
} else{
|
} else{
|
||||||
|
|
||||||
input = `<select class="form-control"
|
input = `<select class="form-control"
|
||||||
id="${columns[j].Code_Name}"
|
id="${columns[j].setKey}"
|
||||||
data-my-column="${columns[j].Code_Name}"
|
data-my-column="${columns[j].setKey}"
|
||||||
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" >
|
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
|
||||||
<option id="${targetLocation}"></option>
|
<option id="${targetLocation}"></option>
|
||||||
</select>`
|
</select>`
|
||||||
}
|
}
|
||||||
@@ -174,20 +174,20 @@
|
|||||||
|
|
||||||
|
|
||||||
input = `<input class="${inputClass}"
|
input = `<input class="${inputClass}"
|
||||||
id="${columns[j].Code_Name}"
|
id="${columns[j].setKey}"
|
||||||
my-customid="${columns[j].Code_Name}"
|
my-customid="${columns[j].setKey}"
|
||||||
data-my-column="${columns[j].Code_Name}"
|
data-my-column="${columns[j].setKey}"
|
||||||
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}"
|
data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}"
|
||||||
type="${inputType}">`
|
type="${inputType}">`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const inputEntry = `<div class="form-group col-sm-12" >
|
const inputEntry = `<div class="form-group col-sm-12" >
|
||||||
<label class="col-sm-3 control-label">${columns[j].Display_Name}</label>
|
<label class="col-sm-3 control-label">${columns[j].setName}</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group red-hover-border">
|
<div class="input-group red-hover-border">
|
||||||
${input}
|
${input}
|
||||||
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${columns[j].Code_Name}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${columns[j].setKey}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
||||||
<i class="fa fa-save"></i>
|
<i class="fa fa-save"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,3 +40,5 @@ $.get('api/table_online_history.json?nocache=' + Date.now(), function(res) {
|
|||||||
console.error('Error fetching online history data.');
|
console.error('Error fetching online history data.');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<!-- <canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas> -->
|
||||||
|
<canvas id="OnlineChart" style="width:100%; height: 150px; margin-bottom: 15px;"></canvas>
|
||||||
@@ -161,6 +161,11 @@ function checkPermissions($files)
|
|||||||
{
|
{
|
||||||
foreach ($files as $file)
|
foreach ($files as $file)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// // make sure the file ownership is correct
|
||||||
|
// chown($file, 'nginx');
|
||||||
|
// chgrp($file, 'www-data');
|
||||||
|
|
||||||
// check access to database
|
// check access to database
|
||||||
if(file_exists($file) != 1)
|
if(file_exists($file) != 1)
|
||||||
{
|
{
|
||||||
@@ -331,7 +336,7 @@ function saveSettings()
|
|||||||
|
|
||||||
foreach ($decodedSettings as $setting) {
|
foreach ($decodedSettings as $setting) {
|
||||||
$settingGroup = $setting[0];
|
$settingGroup = $setting[0];
|
||||||
$settingKey = $setting[1];
|
$setKey = $setting[1];
|
||||||
$dataType = $setting[2];
|
$dataType = $setting[2];
|
||||||
$settingValue = $setting[3];
|
$settingValue = $setting[3];
|
||||||
|
|
||||||
@@ -339,7 +344,7 @@ function saveSettings()
|
|||||||
// $settingType = json_decode($settingTypeJson, true);
|
// $settingType = json_decode($settingTypeJson, true);
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if($settingKey == "UI_LANG" && $settingValue == "") {
|
if($setKey == "UI_LANG" && $settingValue == "") {
|
||||||
echo "🔴 Error: important settings missing. Refresh the page with 🔃 on the top and try again.";
|
echo "🔴 Error: important settings missing. Refresh the page with 🔃 on the top and try again.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -348,14 +353,14 @@ function saveSettings()
|
|||||||
|
|
||||||
if ($dataType == 'string' ) {
|
if ($dataType == 'string' ) {
|
||||||
$val = encode_single_quotes($settingValue);
|
$val = encode_single_quotes($settingValue);
|
||||||
$txt .= $settingKey . "='" . $val . "'\n";
|
$txt .= $setKey . "='" . $val . "'\n";
|
||||||
} elseif ($dataType == 'integer') {
|
} elseif ($dataType == 'integer') {
|
||||||
$txt .= $settingKey . "=" . $settingValue . "\n";
|
$txt .= $setKey . "=" . $settingValue . "\n";
|
||||||
} elseif ($dataType == 'json') {
|
} elseif ($dataType == 'json') {
|
||||||
$txt .= $settingKey . "=" . $settingValue . "\n";
|
$txt .= $setKey . "=" . $settingValue . "\n";
|
||||||
} elseif ($dataType == 'boolean') {
|
} elseif ($dataType == 'boolean') {
|
||||||
$val = ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') ? "True" : "False";
|
$val = ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') ? "True" : "False";
|
||||||
$txt .= $settingKey . "=" . $val . "\n";
|
$txt .= $setKey . "=" . $val . "\n";
|
||||||
} elseif ($dataType == 'array' ) {
|
} elseif ($dataType == 'array' ) {
|
||||||
$temp = '';
|
$temp = '';
|
||||||
|
|
||||||
@@ -373,18 +378,16 @@ function saveSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
$temp = '['.$temp.']'; // wrap brackets
|
$temp = '['.$temp.']'; // wrap brackets
|
||||||
$txt .= $settingKey . "=" . $temp . "\n";
|
$txt .= $setKey . "=" . $temp . "\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$txt .= $settingKey . "='⭕Not handled⭕'\n";
|
$txt .= $setKey . "='⭕Not handled⭕'\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$txt = $txt."\n\n";
|
$txt = $txt."\n\n";
|
||||||
$txt = $txt."#-------------------IMPORTANT INFO-------------------#\n";
|
$txt = $txt."#-------------------IMPORTANT INFO-------------------#\n";
|
||||||
$txt = $txt."# This file is ingested by a python script, so if #\n";
|
$txt = $txt."# This file is ingested by a python script, so if #\n";
|
||||||
@@ -395,13 +398,15 @@ function saveSettings()
|
|||||||
// Create a temporary file
|
// Create a temporary file
|
||||||
$tempConfPath = $fullConfPath . ".tmp";
|
$tempConfPath = $fullConfPath . ".tmp";
|
||||||
|
|
||||||
// Write your changes to the temporary file
|
// Backup the original file
|
||||||
$tempConfig = fopen($tempConfPath, "w") or die("Unable to open file!");
|
if (file_exists($fullConfPath)) {
|
||||||
fwrite($tempConfig, $txt);
|
copy($fullConfPath, $fullConfPath . ".bak");
|
||||||
fclose($tempConfig);
|
}
|
||||||
|
|
||||||
// Replace the original file with the temporary file
|
// Open the file for writing without changing permissions
|
||||||
rename($tempConfPath, $fullConfPath);
|
$file = fopen($fullConfPath, "w") or die("Unable to open file!");
|
||||||
|
fwrite($file, $txt);
|
||||||
|
fclose($file);
|
||||||
|
|
||||||
// displayMessage(lang('settings_saved'),
|
// displayMessage(lang('settings_saved'),
|
||||||
// FALSE, TRUE, TRUE, TRUE);
|
// FALSE, TRUE, TRUE, TRUE);
|
||||||
@@ -411,9 +416,9 @@ function saveSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
function getString ($codeName, $default) {
|
function getString ($setKey, $default) {
|
||||||
|
|
||||||
$result = lang($codeName);
|
$result = lang($setKey);
|
||||||
|
|
||||||
if ($result )
|
if ($result )
|
||||||
{
|
{
|
||||||
@@ -423,7 +428,7 @@ function getString ($codeName, $default) {
|
|||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
function getSettingValue($codeName) {
|
function getSettingValue($setKey) {
|
||||||
// Define the JSON endpoint URL
|
// Define the JSON endpoint URL
|
||||||
$url = dirname(__FILE__).'/../../../front/api/table_settings.json';
|
$url = dirname(__FILE__).'/../../../front/api/table_settings.json';
|
||||||
|
|
||||||
@@ -443,16 +448,16 @@ function getSettingValue($codeName) {
|
|||||||
return 'Could not decode json data';
|
return 'Could not decode json data';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for the setting by Code_Name
|
// Search for the setting by setKey
|
||||||
foreach ($data['data'] as $setting) {
|
foreach ($data['data'] as $setting) {
|
||||||
if ($setting['Code_Name'] === $codeName) {
|
if ($setting['setKey'] === $setKey) {
|
||||||
return $setting['Value'];
|
return $setting['setValue'];
|
||||||
// echo $setting['Value'];
|
// echo $setting['setValue'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return false if the setting was not found
|
// Return false if the setting was not found
|
||||||
return 'Could not find setting '.$codeName;
|
return 'Could not find setting '.$setKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ $allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no",
|
|||||||
|
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
$result = $db->querySingle("SELECT Value FROM Settings WHERE Code_Name = 'UI_LANG'");
|
$result = $db->querySingle("SELECT setValue FROM Settings WHERE setKey = 'UI_LANG'");
|
||||||
|
|
||||||
// below has to match exactly teh values in /front/php/templates/language/lang.php & /front/js/common.js
|
// below has to match exactly teh values in /front/php/templates/language/lang.php & /front/js/common.js
|
||||||
switch($result){
|
switch($result){
|
||||||
|
|||||||
@@ -922,7 +922,7 @@
|
|||||||
{
|
{
|
||||||
"name": "value",
|
"name": "value",
|
||||||
"type": "sql",
|
"type": "sql",
|
||||||
"value": "SELECT '❌None' as name, '' as id UNION SELECT devName as name, devMac as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(devType) || '%' AND devType <> '')"
|
"value": "SELECT '❌None' as name, '' as id UNION SELECT devName as name, devMac as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE setKey = 'NETWORK_DEVICE_TYPES' AND LOWER(setValue) LIKE '%' || LOWER(devType) || '%' AND devType <> '')"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "target_macs",
|
"name": "target_macs",
|
||||||
@@ -1006,7 +1006,7 @@
|
|||||||
{
|
{
|
||||||
"name": "value",
|
"name": "value",
|
||||||
"type": "sql",
|
"type": "sql",
|
||||||
"value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT devIcon AS name, devIcon AS id FROM Devices WHERE devIcon <> '') AS combined_results;"
|
"value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(setValue, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE setKey = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT devIcon AS name, devIcon AS id FROM Devices WHERE devIcon <> '') AS combined_results;"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"localized": ["name", "description"],
|
"localized": ["name", "description"],
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
<?php
|
<?php
|
||||||
require 'php/templates/header.php';
|
require 'php/templates/header.php';
|
||||||
require 'php/components/graph_online_history.php';
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- Page ------------------------------------------------------------------ -->
|
<!-- Page ------------------------------------------------------------------ -->
|
||||||
@@ -117,8 +116,10 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<script src="lib/AdminLTE/bower_components/chart.js/Chart.js"></script>
|
<script src="lib/AdminLTE/bower_components/chart.js/Chart.js"></script>
|
||||||
<!-- <canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas> -->
|
<!-- presence chart -->
|
||||||
<canvas id="OnlineChart" style="width:100%; height: 150px; margin-bottom: 15px;"></canvas>
|
<?php
|
||||||
|
require 'php/components/graph_online_history.php';
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.box-body -->
|
<!-- /.box-body -->
|
||||||
|
|||||||
@@ -33,15 +33,14 @@ $result = $db->query("SELECT * FROM Settings");
|
|||||||
$settings = array();
|
$settings = array();
|
||||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||||
// Push row data
|
// Push row data
|
||||||
$settings[] = array( 'Code_Name' => $row['Code_Name'],
|
$settings[] = array( 'setKey' => $row['setKey'],
|
||||||
'Display_Name' => $row['Display_Name'],
|
'setName' => $row['setName'],
|
||||||
'Description' => $row['Description'],
|
'setDescription' => $row['setDescription'],
|
||||||
'Type' => $row['Type'],
|
'setType' => $row['setType'],
|
||||||
'Options' => $row['Options'],
|
'setOptions' => $row['setOptions'],
|
||||||
'RegEx' => $row['RegEx'],
|
'setValue' => $row['setValue'],
|
||||||
'Value' => $row['Value'],
|
'setGroup' => $row['setGroup'],
|
||||||
'Group' => $row['Group'],
|
'setEvents' => $row['setEvents']
|
||||||
'Events' => $row['Events']
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,12 +194,12 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
pluginsData = res["data"];
|
pluginsData = res["data"];
|
||||||
|
|
||||||
// Sort settingsData alphabetically based on the "Group" property
|
// Sort settingsData alphabetically based on the "setGroup" property
|
||||||
settingsData.sort((a, b) => {
|
settingsData.sort((a, b) => {
|
||||||
if (a["Group"] < b["Group"]) {
|
if (a["setGroup"] < b["setGroup"]) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (a["Group"] > b["Group"]) {
|
if (a["setGroup"] > b["setGroup"]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -214,15 +213,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
// let's use that to verify settings were initialized correctly
|
// let's use that to verify settings were initialized correctly
|
||||||
settingsData.forEach((set) => {
|
settingsData.forEach((set) => {
|
||||||
|
|
||||||
codeName = set['Code_Name']
|
setKey = set['setKey']
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isMetadata = codeName.includes('__metadata');
|
const isMetadata = setKey.includes('__metadata');
|
||||||
// if this isn't a metadata entry, get corresponding metadata object from the dummy setting
|
// if this isn't a metadata entry, get corresponding metadata object from the dummy setting
|
||||||
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${codeName}__metadata`));
|
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${setKey}__metadata`));
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error getting setting for ${codeName}:`, error);
|
console.error(`Error getting setting for ${setKey}:`, error);
|
||||||
showModalOk('WARNING', "Outdated cache - refreshing (refresh browser cache if needed)");
|
showModalOk('WARNING', "Outdated cache - refreshing (refresh browser cache if needed)");
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -260,8 +259,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
settingsData.forEach((set) => {
|
settingsData.forEach((set) => {
|
||||||
// settingPluginPrefixes
|
// settingPluginPrefixes
|
||||||
if (!settingPluginPrefixes.includes(set.Group)) {
|
if (!settingPluginPrefixes.includes(set.setGroup)) {
|
||||||
settingPluginPrefixes.push(set.Group); // = Unique plugin prefix
|
settingPluginPrefixes.push(set.setGroup); // = Unique plugin prefix
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -375,36 +374,36 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
// go thru all settings and collect settings per settings prefix
|
// go thru all settings and collect settings per settings prefix
|
||||||
settingsData.forEach((set) => {
|
settingsData.forEach((set) => {
|
||||||
|
|
||||||
const valIn = set['Value'];
|
const valIn = set['setValue'];
|
||||||
const codeName = set['Code_Name'];
|
const setKey = set['setKey'];
|
||||||
const overriddenByEnv = set['OverriddenByEnv'] == 1;
|
const overriddenByEnv = set['setOverriddenByEnv'] == 1;
|
||||||
const setType = set['Type'];
|
const setType = set['setType'];
|
||||||
const isMetadata = codeName.includes('__metadata');
|
const isMetadata = setKey.includes('__metadata');
|
||||||
// is this isn't a metadata entry, get corresponding metadata object from the dummy setting
|
// is this isn't a metadata entry, get corresponding metadata object from the dummy setting
|
||||||
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${codeName}__metadata`));
|
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${setKey}__metadata`));
|
||||||
|
|
||||||
// not initialized properly, reload
|
// not initialized properly, reload
|
||||||
if(isMetadata && valIn == "" )
|
if(isMetadata && valIn == "" )
|
||||||
{
|
{
|
||||||
console.warn(`Metadata setting value is empty: ${codeName}`);
|
console.warn(`Metadata setting value is empty: ${setKey}`);
|
||||||
clearCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructing final HTML for the setting
|
// constructing final HTML for the setting
|
||||||
setHtml = ""
|
setHtml = ""
|
||||||
|
|
||||||
if(set["Group"] == prefix)
|
if(set["setGroup"] == prefix)
|
||||||
{
|
{
|
||||||
// hide metadata by default by assigning it a special class
|
// hide metadata by default by assigning it a special class
|
||||||
isMetadata ? metadataClass = 'metadata' : metadataClass = '';
|
isMetadata ? metadataClass = 'metadata' : metadataClass = '';
|
||||||
isMetadata ? showMetadata = '' : showMetadata = `<i
|
isMetadata ? showMetadata = '' : showMetadata = `<i
|
||||||
my-to-toggle="row_${codeName}__metadata"
|
my-to-toggle="row_${setKey}__metadata"
|
||||||
title="${getString("Settings_Metadata_Toggle")}"
|
title="${getString("Settings_Metadata_Toggle")}"
|
||||||
class="fa fa-circle-question pointer hideOnMobile"
|
class="fa fa-circle-question pointer hideOnMobile"
|
||||||
onclick="toggleMetadata(this)">
|
onclick="toggleMetadata(this)">
|
||||||
</i>` ;
|
</i>` ;
|
||||||
|
|
||||||
infoIcon = `<i my-to-show="#row_${codeName} .setting_description"
|
infoIcon = `<i my-to-show="#row_${setKey} .setting_description"
|
||||||
title="${getString("Settings_Show_Description")}"
|
title="${getString("Settings_Show_Description")}"
|
||||||
class="fa fa-circle-info pointer hideOnBigScreen"
|
class="fa fa-circle-info pointer hideOnBigScreen"
|
||||||
onclick="showDescription(this)">
|
onclick="showDescription(this)">
|
||||||
@@ -412,15 +411,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
// NAME & DESCRIPTION columns
|
// NAME & DESCRIPTION columns
|
||||||
setHtml += `
|
setHtml += `
|
||||||
<div class="row table_row ${metadataClass} " id="row_${codeName}">
|
<div class="row table_row ${metadataClass} " id="row_${setKey}">
|
||||||
<div class="table_cell setting_name bold col-sm-2">
|
<div class="table_cell setting_name bold col-sm-2">
|
||||||
<label>${getString(codeName + '_name', set['Display_Name'])}</label>
|
<label>${getString(setKey + '_name', set['setName'])}</label>
|
||||||
<div class="small text-overflow-hidden">
|
<div class="small text-overflow-hidden">
|
||||||
<code>${codeName}</code>${showMetadata}${infoIcon}
|
<code>${setKey}</code>${showMetadata}${infoIcon}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="table_cell setting_description col-sm-4">
|
<div class="table_cell setting_description col-sm-4">
|
||||||
${getString(codeName + '_description', set['Description'])}
|
${getString(setKey + '_description', set['setDescription'])}
|
||||||
</div>
|
</div>
|
||||||
<div class="table_cell input-group setting_input ${overriddenByEnv ? "setting_overriden_by_env" : ""} input-group col-xs-12 col-sm-6">
|
<div class="table_cell input-group setting_input ${overriddenByEnv ? "setting_overriden_by_env" : ""} input-group col-xs-12 col-sm-6">
|
||||||
`;
|
`;
|
||||||
@@ -455,7 +454,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
|
|
||||||
overrideHtml = `<div class="override col-xs-12">
|
overrideHtml = `<div class="override col-xs-12">
|
||||||
<div class="override-check col-xs-1">
|
<div class="override-check col-xs-1">
|
||||||
<input onChange="overrideToggle(this)" my-data-type="${setType}" my-input-toggle-readonly="${codeName}" class="checkbox" id="${codeName}_override" type="checkbox" ${checked} />
|
<input onChange="overrideToggle(this)" my-data-type="${setType}" my-input-toggle-readonly="${setKey}" class="checkbox" id="${setKey}_override" type="checkbox" ${checked} />
|
||||||
</div>
|
</div>
|
||||||
<div class="override-text col-xs-11" title="${getString("Setting_Override_Description")}">
|
<div class="override-text col-xs-11" title="${getString("Setting_Override_Description")}">
|
||||||
${getString("Setting_Override")}
|
${getString("Setting_Override")}
|
||||||
@@ -469,7 +468,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
// Parse the setType JSON string into an object
|
// Parse the setType JSON string into an object
|
||||||
let inputHtml = '';
|
let inputHtml = '';
|
||||||
|
|
||||||
console.log(codeName);
|
console.log(setKey);
|
||||||
console.log(setType);
|
console.log(setType);
|
||||||
|
|
||||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
||||||
@@ -497,7 +496,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
onChange,
|
onChange,
|
||||||
customParams,
|
customParams,
|
||||||
customId
|
customId
|
||||||
} = handleElementOptions(codeName, elementOptions, transformers, valIn);
|
} = handleElementOptions(setKey, elementOptions, transformers, valIn);
|
||||||
|
|
||||||
// override
|
// override
|
||||||
val = valRes;
|
val = valRes;
|
||||||
@@ -513,15 +512,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
my-editable="${editable}"
|
my-editable="${editable}"
|
||||||
class="form-control ${addCss}"
|
class="form-control ${addCss}"
|
||||||
name="${codeName}"
|
name="${setKey}"
|
||||||
id="${codeName}"
|
id="${setKey}"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
${multi}>
|
${multi}>
|
||||||
<option value="" id="${codeName + "_temp_"}"></option>
|
<option value="" id="${setKey + "_temp_"}"></option>
|
||||||
</select>`;
|
</select>`;
|
||||||
|
|
||||||
generateOptionsOrSetOptions(codeName, createArray(val), `${codeName}_temp_`, generateOptions, targetField = null, transformers);
|
generateOptionsOrSetOptions(setKey, createArray(val), `${setKey}_temp_`, generateOptions, targetField = null, transformers);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -536,7 +535,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
id="${codeName}${suffix}"
|
id="${setKey}${suffix}"
|
||||||
type="${inputType}"
|
type="${inputType}"
|
||||||
value="${val}"
|
value="${val}"
|
||||||
${readOnly}
|
${readOnly}
|
||||||
@@ -553,7 +552,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
my-input-from="${sourceIds}"
|
my-input-from="${sourceIds}"
|
||||||
my-input-to="${codeName}"
|
my-input-to="${setKey}"
|
||||||
onclick="${onClick}">
|
onclick="${onClick}">
|
||||||
${getString(getStringKey)}
|
${getString(getStringKey)}
|
||||||
</button>`;
|
</button>`;
|
||||||
@@ -565,7 +564,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
my-customparams="${customParams}"
|
my-customparams="${customParams}"
|
||||||
my-customid="${customId}"
|
my-customid="${customId}"
|
||||||
my-data-type="${dataType}"
|
my-data-type="${dataType}"
|
||||||
id="${codeName}"
|
id="${setKey}"
|
||||||
${readOnly}>
|
${readOnly}>
|
||||||
${val}
|
${val}
|
||||||
</textarea>`;
|
</textarea>`;
|
||||||
@@ -591,13 +590,13 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
// process events (e.g. run a scan, or test a notification) if associated with the setting
|
// process events (e.g. run a scan, or test a notification) if associated with the setting
|
||||||
let eventsHtml = "";
|
let eventsHtml = "";
|
||||||
|
|
||||||
const eventsList = createArray(set['Events']);
|
const eventsList = createArray(set['setEvents']);
|
||||||
|
|
||||||
if (eventsList.length > 0) {
|
if (eventsList.length > 0) {
|
||||||
// console.log(eventsList)
|
// console.log(eventsList)
|
||||||
eventsList.forEach(event => {
|
eventsList.forEach(event => {
|
||||||
eventsHtml += `<span class="input-group-addon pointer"
|
eventsHtml += `<span class="input-group-addon pointer"
|
||||||
data-myparam="${codeName}"
|
data-myparam="${setKey}"
|
||||||
data-myparam-plugin="${prefix}"
|
data-myparam-plugin="${prefix}"
|
||||||
data-myevent="${event}"
|
data-myevent="${event}"
|
||||||
onclick="addToExecutionQueue_settingEvent(this)"
|
onclick="addToExecutionQueue_settingEvent(this)"
|
||||||
@@ -666,9 +665,9 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
|||||||
// loop through the settings definitions from the json
|
// loop through the settings definitions from the json
|
||||||
res["data"].forEach(set => {
|
res["data"].forEach(set => {
|
||||||
|
|
||||||
prefix = set["Group"]
|
prefix = set["setGroup"]
|
||||||
setType = set["Type"]
|
setType = set["setType"]
|
||||||
setCodeName = set["Code_Name"]
|
setCodeName = set["setKey"]
|
||||||
|
|
||||||
console.log(prefix);
|
console.log(prefix);
|
||||||
|
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ sql_appevents = """select * from AppEvents"""
|
|||||||
# as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting
|
# as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting
|
||||||
sql_devices_tiles = """
|
sql_devices_tiles = """
|
||||||
WITH Statuses AS (
|
WITH Statuses AS (
|
||||||
SELECT Value
|
SELECT setValue
|
||||||
FROM Settings
|
FROM Settings
|
||||||
WHERE Code_Name = 'UI_MY_DEVICES'
|
WHERE setKey = 'UI_MY_DEVICES'
|
||||||
),
|
),
|
||||||
MyDevicesFilter AS (
|
MyDevicesFilter AS (
|
||||||
SELECT
|
SELECT
|
||||||
@@ -87,11 +87,11 @@ sql_devices_tiles = """
|
|||||||
devPresentLastScan, devAlertDown, devIsNew, devIsArchived
|
devPresentLastScan, devAlertDown, devIsNew, devIsArchived
|
||||||
FROM Devices
|
FROM Devices
|
||||||
WHERE
|
WHERE
|
||||||
(instr((SELECT Value FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
|
(instr((SELECT setValue FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
|
||||||
(instr((SELECT Value FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0) OR
|
(instr((SELECT setValue FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0) OR
|
||||||
(instr((SELECT Value FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
|
(instr((SELECT setValue FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
|
||||||
(instr((SELECT Value FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
|
(instr((SELECT setValue FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
|
||||||
(instr((SELECT Value FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
|
(instr((SELECT setValue FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
-- Counts for each individual status
|
-- Counts for each individual status
|
||||||
|
|||||||
@@ -487,16 +487,15 @@ class DB():
|
|||||||
self.sql.execute(""" DROP TABLE IF EXISTS Settings;""")
|
self.sql.execute(""" DROP TABLE IF EXISTS Settings;""")
|
||||||
self.sql.execute("""
|
self.sql.execute("""
|
||||||
CREATE TABLE "Settings" (
|
CREATE TABLE "Settings" (
|
||||||
"Code_Name" TEXT,
|
"setKey" TEXT,
|
||||||
"Display_Name" TEXT,
|
"setName" TEXT,
|
||||||
"Description" TEXT,
|
"setDescription" TEXT,
|
||||||
"Type" TEXT,
|
"setType" TEXT,
|
||||||
"Options" TEXT,
|
"setOptions" TEXT,
|
||||||
"RegEx" TEXT,
|
"setGroup" TEXT,
|
||||||
"Group" TEXT,
|
"setValue" TEXT,
|
||||||
"Value" TEXT,
|
"setEvents" TEXT,
|
||||||
"Events" TEXT,
|
"setOverriddenByEnv" INTEGER
|
||||||
"OverriddenByEnv" INTEGER
|
|
||||||
);
|
);
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ app = Flask(__name__)
|
|||||||
# Retrieve API token and port
|
# Retrieve API token and port
|
||||||
graphql_port_value = get_setting_value("GRAPHQL_PORT")
|
graphql_port_value = get_setting_value("GRAPHQL_PORT")
|
||||||
|
|
||||||
|
# Endpoint used when accessed via browser
|
||||||
|
@app.route("/graphql", methods=["GET"])
|
||||||
|
def graphql_debug():
|
||||||
|
# Handles GET requests
|
||||||
|
return "NetAlertX GraphQL server running."
|
||||||
|
|
||||||
# Endpoint for GraphQL queries
|
# Endpoint for GraphQL queries
|
||||||
@app.route("/graphql", methods=["POST"])
|
@app.route("/graphql", methods=["POST"])
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ def get_setting(key):
|
|||||||
data = json.load(json_file)
|
data = json.load(json_file)
|
||||||
|
|
||||||
for item in data.get("data",[]):
|
for item in data.get("data",[]):
|
||||||
if item.get("Code_Name") == key:
|
if item.get("setKey") == key:
|
||||||
return item
|
return item
|
||||||
|
|
||||||
mylog('debug', [f'[Settings] ⚠ ERROR - setting_missing - Setting not found for key: {key} in file {settingsFile}'])
|
mylog('debug', [f'[Settings] ⚠ ERROR - setting_missing - Setting not found for key: {key} in file {settingsFile}'])
|
||||||
@@ -327,8 +327,8 @@ def get_setting_value(key):
|
|||||||
set_type = 'Error: Not handled'
|
set_type = 'Error: Not handled'
|
||||||
set_value = 'Error: Not handled'
|
set_value = 'Error: Not handled'
|
||||||
|
|
||||||
set_value = setting["Value"] # Setting value (Value (upper case) = user overridden default_value)
|
set_value = setting["setValue"] # Setting value (Value (upper case) = user overridden default_value)
|
||||||
set_type = setting["Type"] # Setting type # lower case "type" - default json value vs uppper-case "Type" (= from user defined settings)
|
set_type = setting["setType"] # Setting type # lower case "type" - default json value vs uppper-case "setType" (= from user defined settings)
|
||||||
|
|
||||||
value = setting_value_to_python_type(set_type, set_value)
|
value = setting_value_to_python_type(set_type, set_value)
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import re
|
|||||||
|
|
||||||
import conf
|
import conf
|
||||||
from const import fullConfPath, applicationPath, fullConfFolder
|
from const import fullConfPath, applicationPath, fullConfFolder
|
||||||
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
|
from helper import fixPermissions, collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
|
||||||
from logger import mylog
|
from logger import mylog
|
||||||
from api import update_api
|
from api import update_api
|
||||||
from scheduler import schedule_class
|
from scheduler import schedule_class
|
||||||
@@ -30,7 +30,7 @@ from notification import write_notification
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# managing application settings, ensuring SQL safety for user input, and updating internal configuration lists
|
# managing application settings, ensuring SQL safety for user input, and updating internal configuration lists
|
||||||
def ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False, overriddenByEnv=0):
|
def ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False, overriddenByEnv=0):
|
||||||
if events is None:
|
if events is None:
|
||||||
events = []
|
events = []
|
||||||
if setJsonMetadata is None:
|
if setJsonMetadata is None:
|
||||||
@@ -51,8 +51,8 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
|
|||||||
|
|
||||||
|
|
||||||
# Create the tuples
|
# Create the tuples
|
||||||
sql_safe_tuple = (key, name, desc, str(inputtype), options, regex, str(result), group, str(events), overriddenByEnv)
|
sql_safe_tuple = (key, name, desc, str(inputtype), options, str(result), group, str(events), overriddenByEnv)
|
||||||
settings_tuple = (key, name, desc, inputtype, options, regex, result, group, str(events), overriddenByEnv)
|
settings_tuple = (key, name, desc, inputtype, options, result, group, str(events), overriddenByEnv)
|
||||||
|
|
||||||
# Update or append the tuples in the lists
|
# Update or append the tuples in the lists
|
||||||
conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, sql_safe_tuple, key)
|
conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, sql_safe_tuple, key)
|
||||||
@@ -60,7 +60,7 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
|
|||||||
|
|
||||||
# Save metadata in dummy setting if not a metadata key
|
# Save metadata in dummy setting if not a metadata key
|
||||||
if '__metadata' not in key:
|
if '__metadata' not in key:
|
||||||
metadata_tuple = (f'{key}__metadata', "metadata name", "metadata desc", '{"dataType":"json", "elements": [{"elementType" : "textarea", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}', '[]', "", json.dumps(setJsonMetadata), group, '[]', overriddenByEnv)
|
metadata_tuple = (f'{key}__metadata', "metadata name", "metadata desc", '{"dataType":"json", "elements": [{"elementType" : "textarea", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}', '[]', json.dumps(setJsonMetadata), group, '[]', overriddenByEnv)
|
||||||
conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, metadata_tuple, f'{key}__metadata')
|
conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, metadata_tuple, f'{key}__metadata')
|
||||||
conf.mySettings = update_or_append(conf.mySettings, metadata_tuple, f'{key}__metadata')
|
conf.mySettings = update_or_append(conf.mySettings, metadata_tuple, f'{key}__metadata')
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ def importConfigs (db, all_plugins):
|
|||||||
# Header
|
# Header
|
||||||
updateState("Import config", showSpinner = True)
|
updateState("Import config", showSpinner = True)
|
||||||
|
|
||||||
# remove all plugin langauge strings
|
# remove all plugin language strings
|
||||||
sql.execute("DELETE FROM Plugins_Language_Strings;")
|
sql.execute("DELETE FROM Plugins_Language_Strings;")
|
||||||
db.commitDB()
|
db.commitDB()
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ def importConfigs (db, all_plugins):
|
|||||||
setting_obj = get_plugin_setting_obj(plugin, "RUN")
|
setting_obj = get_plugin_setting_obj(plugin, "RUN")
|
||||||
|
|
||||||
if setting_obj is not None:
|
if setting_obj is not None:
|
||||||
set_type = setting_obj.get('type') # lower case "type" - default json value vs uppper-case "Type" (= from user defined settings)
|
set_type = setting_obj.get('type') # lower case "type" - default json value vs uppper-case "setType" (= from user defined settings)
|
||||||
set_value = setting_obj.get('default_value')
|
set_value = setting_obj.get('default_value')
|
||||||
|
|
||||||
plugin_run = setting_value_to_python_type(set_type, set_value)
|
plugin_run = setting_value_to_python_type(set_type, set_value)
|
||||||
@@ -239,7 +239,7 @@ def importConfigs (db, all_plugins):
|
|||||||
key = pref + "_" + setFunction
|
key = pref + "_" + setFunction
|
||||||
|
|
||||||
# set.get() - returns None if not found, set["options"] raises error
|
# set.get() - returns None if not found, set["options"] raises error
|
||||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=[], desc = "", regex = "", setJsonMetadata = {}):
|
# ccd(key, default, config_dir, name, inputtype, options, group, events=[], desc = "", setJsonMetadata = {}):
|
||||||
v = ccd(key,
|
v = ccd(key,
|
||||||
set["default_value"],
|
set["default_value"],
|
||||||
c_d,
|
c_d,
|
||||||
@@ -249,7 +249,6 @@ def importConfigs (db, all_plugins):
|
|||||||
group = pref,
|
group = pref,
|
||||||
events = set.get("events"),
|
events = set.get("events"),
|
||||||
desc = set["description"][0]["string"],
|
desc = set["description"][0]["string"],
|
||||||
regex = "",
|
|
||||||
setJsonMetadata = set)
|
setJsonMetadata = set)
|
||||||
|
|
||||||
# Save the user defined value into the object
|
# Save the user defined value into the object
|
||||||
@@ -323,9 +322,9 @@ def importConfigs (db, all_plugins):
|
|||||||
value = str(value)
|
value = str(value)
|
||||||
|
|
||||||
# Log the value being passed
|
# Log the value being passed
|
||||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
||||||
mylog('verbose', [f"[Config] Setting override {setting_name} with value: {value}"])
|
mylog('verbose', [f"[Config] Setting override {setting_name} with value: {value}"])
|
||||||
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
|
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True, 1)
|
||||||
|
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"])
|
mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"])
|
||||||
@@ -348,8 +347,8 @@ def importConfigs (db, all_plugins):
|
|||||||
|
|
||||||
mylog('none', ['[Config] App upgraded 🚀'])
|
mylog('none', ['[Config] App upgraded 🚀'])
|
||||||
|
|
||||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
||||||
ccd('VERSION', buildTimestamp , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True)
|
ccd('VERSION', buildTimestamp , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True)
|
||||||
|
|
||||||
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
|
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
|
||||||
|
|
||||||
@@ -360,8 +359,8 @@ def importConfigs (db, all_plugins):
|
|||||||
# Insert settings into the DB
|
# Insert settings into the DB
|
||||||
sql.execute ("DELETE FROM Settings")
|
sql.execute ("DELETE FROM Settings")
|
||||||
# mylog('debug', [f"[Config] conf.mySettingsSQLsafe : '{conf.mySettingsSQLsafe}'"])
|
# mylog('debug', [f"[Config] conf.mySettingsSQLsafe : '{conf.mySettingsSQLsafe}'"])
|
||||||
sql.executemany ("""INSERT INTO Settings ("Code_Name", "Display_Name", "Description", "Type", "Options",
|
sql.executemany ("""INSERT INTO Settings ("setKey", "setName", "setDescription", "setType", "setOptions",
|
||||||
"RegEx", "Value", "Group", "Events", "OverriddenByEnv" ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", conf.mySettingsSQLsafe)
|
"setValue", "setGroup", "setEvents", "setOverriddenByEnv" ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""", conf.mySettingsSQLsafe)
|
||||||
|
|
||||||
db.commitDB()
|
db.commitDB()
|
||||||
|
|
||||||
@@ -420,7 +419,7 @@ replacements = {
|
|||||||
r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
|
r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
|
||||||
r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
|
r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
|
||||||
r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
|
r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
|
||||||
r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
|
# r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
|
||||||
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
|
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
|
||||||
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
|
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
|
||||||
r'dev_MAC': 'devMac',
|
r'dev_MAC': 'devMac',
|
||||||
@@ -463,6 +462,7 @@ def renameSettings(config_file):
|
|||||||
for line in original_file:
|
for line in original_file:
|
||||||
# Use regular expressions with word boundaries to check for the old setting code names
|
# Use regular expressions with word boundaries to check for the old setting code names
|
||||||
if any(re.search(key, line) for key in replacements.keys()):
|
if any(re.search(key, line) for key in replacements.keys()):
|
||||||
|
mylog('debug', f'[Config] Old setting names found in line: ({line})')
|
||||||
contains_old_settings = True
|
contains_old_settings = True
|
||||||
break # Exit the loop if any old setting is found
|
break # Exit the loop if any old setting is found
|
||||||
|
|
||||||
@@ -492,6 +492,9 @@ def renameSettings(config_file):
|
|||||||
|
|
||||||
# Replace the original config_file with the temporary file
|
# Replace the original config_file with the temporary file
|
||||||
shutil.move(str(config_file) + "_temp", str(config_file)) # Convert config_file to a string
|
shutil.move(str(config_file) + "_temp", str(config_file)) # Convert config_file to a string
|
||||||
|
|
||||||
|
# ensure correct ownership
|
||||||
|
fixPermissions()
|
||||||
else:
|
else:
|
||||||
mylog('debug', '[Config] No old setting names found in the file. No changes made.')
|
mylog('debug', '[Config] No old setting names found in the file. No changes made.')
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class plugin_param:
|
|||||||
inputValue = get_setting(param["value"])
|
inputValue = get_setting(param["value"])
|
||||||
|
|
||||||
if inputValue != None:
|
if inputValue != None:
|
||||||
setVal = inputValue["Value"] # setting value
|
setVal = inputValue["setValue"] # setting value
|
||||||
setTyp = inputValue["Type"] # setting type
|
setTyp = inputValue["setType"] # setting type
|
||||||
|
|
||||||
setTypJSN = json.loads(setTyp.replace('"','\"').replace("'",'"'))
|
setTypJSN = json.loads(setTyp.replace('"','\"').replace("'",'"'))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user