dynamic dropdown support in FE - core app feature 💠
This commit is contained in:
@@ -189,12 +189,10 @@
|
|||||||
<!-- ----------------------------------------------------------------------- -->
|
<!-- ----------------------------------------------------------------------- -->
|
||||||
<!-- Datatable -->
|
<!-- Datatable -->
|
||||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="lib/AdminLTE/bower_components/datatables.net/css/select.dataTables.min.css">
|
||||||
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
<script src="lib/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
<script src="lib/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css">
|
<script src="lib/AdminLTE/bower_components/datatables.net/js/dataTables.select.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js"></script>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- page script ----------------------------------------------------------- -->
|
<!-- page script ----------------------------------------------------------- -->
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
18
front/js/db_methods.js
Executable file
18
front/js/db_methods.js
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// General utilities to interact with teh database
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Read data and place intotarget location, callback processies the results
|
||||||
|
function readData(sqlQuery, processDataCallback, targetLocation) {
|
||||||
|
var apiUrl = `php/server/dbHelper.php?action=read&rawSql=${encodeURIComponent(sqlQuery)}`;
|
||||||
|
$.get(apiUrl, function(data) {
|
||||||
|
// Process the JSON data using the provided callback function
|
||||||
|
|
||||||
|
data = JSON.parse(data)
|
||||||
|
|
||||||
|
var htmlResult = processDataCallback(data);
|
||||||
|
|
||||||
|
// Place the resulting HTML into the specified placeholder div
|
||||||
|
$("#" + targetLocation).replaceWith(htmlResult);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -112,14 +112,41 @@ function deleteAllCookies() {
|
|||||||
function cacheSettings()
|
function cacheSettings()
|
||||||
{
|
{
|
||||||
|
|
||||||
$.get('api/table_settings.json?nocache=' + Date.now(), function(res) {
|
$.get('api/table_settings.json?nocache=' + Date.now(), function(resSet) {
|
||||||
|
|
||||||
settingsJSON = res;
|
$.get('api/plugins.json?nocache=' + Date.now(), function(resPlug) {
|
||||||
|
|
||||||
|
pluginsData = resPlug["data"];
|
||||||
|
settingsData = resSet["data"];
|
||||||
|
|
||||||
|
settingsData.forEach((set) => {
|
||||||
|
|
||||||
|
resolvedValue = set.Value;
|
||||||
|
setPlugObj = {};
|
||||||
|
options_params = [];
|
||||||
|
|
||||||
|
|
||||||
|
setPlugObj = getPluginSettingObject(pluginsData, set.Code_Name)
|
||||||
|
|
||||||
|
|
||||||
|
if(setPlugObj != {} && setPlugObj["options_params"])
|
||||||
|
{
|
||||||
|
options_params = setPlugObj["options_params"]
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if options contains parameters and resolve
|
||||||
|
if(set.Value.includes("{value}"))
|
||||||
|
{
|
||||||
|
|
||||||
|
resolvedValue = resolveParams(options_params, set.Value)
|
||||||
|
|
||||||
|
console.log(resolvedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
setCache(`pia_set_${set.Code_Name}`, resolvedValue)
|
||||||
|
});
|
||||||
|
|
||||||
data = settingsJSON["data"];
|
|
||||||
|
|
||||||
data.forEach((set) => {
|
|
||||||
setCache(`pia_set_${set.Code_Name}`, set.Value)
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -146,6 +173,8 @@ function getSetting (key) {
|
|||||||
function cacheStrings()
|
function cacheStrings()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
console.log("aaaaaaaaaaaaaaaaaaaaaa")
|
||||||
|
|
||||||
// handle core strings and translations
|
// handle core strings and translations
|
||||||
var allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "ru_ru", "nb_no"]; // needs to be same as in lang.php
|
var allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "ru_ru", "nb_no"]; // needs to be same as in lang.php
|
||||||
|
|
||||||
@@ -907,7 +936,77 @@ function setupSmoothScrolling() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Function to check if options_params contains a parameter with type "sql"
|
||||||
|
function hasSqlType(params) {
|
||||||
|
for (let param of params) {
|
||||||
|
if (param.type === "sql") {
|
||||||
|
return true; // Found a parameter with type "sql"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // No parameter with type "sql" found
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Function to check if string is SQL query
|
||||||
|
function isSQLQuery(query) {
|
||||||
|
// Regular expression to match common SQL keywords and syntax with word boundaries
|
||||||
|
var sqlRegex = /\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|FROM|JOIN|WHERE|SET|VALUES|GROUP BY|ORDER BY|LIMIT)\b/i;
|
||||||
|
|
||||||
|
return sqlRegex.test(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Get corresponding plugin setting object
|
||||||
|
function getPluginSettingObject(pluginsData, setting_key, unique_prefix ) {
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
unique_prefix == undefined ? unique_prefix = setting_key.split("_")[0] : unique_prefix = unique_prefix;
|
||||||
|
|
||||||
|
$.each(pluginsData, function (i, plgnObj){
|
||||||
|
// go thru plugins
|
||||||
|
if(plgnObj.unique_prefix == unique_prefix)
|
||||||
|
{
|
||||||
|
// go thru plugin settings
|
||||||
|
$.each(plgnObj["settings"], function (j, setObj){
|
||||||
|
|
||||||
|
if(`${unique_prefix}_${setObj.function}` == setting_key)
|
||||||
|
{
|
||||||
|
result = setObj
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Resolve all option parameters
|
||||||
|
function resolveParams(params, template) {
|
||||||
|
params.forEach(param => {
|
||||||
|
// Check if the template includes the parameter name
|
||||||
|
if (template.includes("{" + param.name + "}")) {
|
||||||
|
// If the parameter type is 'setting', retrieve setting value
|
||||||
|
if (param.type == "setting") {
|
||||||
|
var value = getSetting(param.value);
|
||||||
|
// Replace placeholder with setting value
|
||||||
|
template = template.replace("{" + param.name + "}", value);
|
||||||
|
} else {
|
||||||
|
// If the parameter type is not 'setting', use the provided value
|
||||||
|
template = template.replace("{" + param.name + "}", param.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log the resolved template
|
||||||
|
console.log(template);
|
||||||
|
|
||||||
|
// Return the resolved template
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// initialize
|
// initialize
|
||||||
@@ -955,8 +1054,11 @@ var pialert_common_init = sessionStorage.getItem(sessionStorageKey) === "true";
|
|||||||
|
|
||||||
// Define a function that will execute the code only once
|
// Define a function that will execute the code only once
|
||||||
function executeOnce() {
|
function executeOnce() {
|
||||||
|
|
||||||
if (!pialert_common_init) {
|
if (!pialert_common_init) {
|
||||||
|
|
||||||
|
console.log("ffffffffffffffffffffffffffffffffffffff")
|
||||||
|
|
||||||
showSpinner()
|
showSpinner()
|
||||||
|
|
||||||
// Your initialization code here
|
// Your initialization code here
|
||||||
@@ -964,7 +1066,8 @@ function executeOnce() {
|
|||||||
cacheStrings();
|
cacheStrings();
|
||||||
initDeviceListAll_JSON();
|
initDeviceListAll_JSON();
|
||||||
|
|
||||||
// Set the flag in sessionStorage to indicate that the code has been executed and save time when last time the page for initialized
|
// Set the flag in sessionStorage to indicate that the code has been executed
|
||||||
|
// and save time when last time the page for initialized
|
||||||
sessionStorage.setItem(sessionStorageKey, "true");
|
sessionStorage.setItem(sessionStorageKey, "true");
|
||||||
const millisecondsNow = Date.now();
|
const millisecondsNow = Date.now();
|
||||||
sessionStorage.setItem(sessionStorageKey + '_time', millisecondsNow);
|
sessionStorage.setItem(sessionStorageKey + '_time', millisecondsNow);
|
||||||
|
|||||||
@@ -164,3 +164,8 @@
|
|||||||
|
|
||||||
return true; // Return true if no schedules are found
|
return true; // Return true if no schedules are found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,74 @@ $(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Initiate dropdown
|
||||||
|
function initSettingDropdown(settingKey, targetLocation)
|
||||||
|
{
|
||||||
|
|
||||||
|
var optionsHtml = ""
|
||||||
|
var targetLocation_options = settingKey + "_initSettingDropdown"
|
||||||
|
|
||||||
|
setVal = getSetting(settingKey)
|
||||||
|
|
||||||
|
// check if the result is a SQL query
|
||||||
|
if(isSQLQuery(setVal))
|
||||||
|
{
|
||||||
|
|
||||||
|
optionsHtml += `<option id="${targetLocation_options}"></option>`;
|
||||||
|
|
||||||
|
readData(setVal, generateDropdownOptions, targetLocation_options);
|
||||||
|
|
||||||
|
} else // this should be already an array, e.g. from a setting or pre-defined
|
||||||
|
{
|
||||||
|
options = createArray(setVal);
|
||||||
|
values = createArray(set['Value']);
|
||||||
|
|
||||||
|
|
||||||
|
options.forEach(option => {
|
||||||
|
let selected = values.includes(option) ? 'selected' : '';
|
||||||
|
optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Place the resulting HTML into the specified placeholder div
|
||||||
|
$("#" + targetLocation).replaceWith(optionsHtml);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Data processors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Processor to generate options for a dropdown menu
|
||||||
|
function generateDropdownOptions(data) {
|
||||||
|
var optionsHtml = "";
|
||||||
|
data.forEach(function(item) {
|
||||||
|
optionsHtml += `<option value="${item.id}">${item.name}</option>`;
|
||||||
|
});
|
||||||
|
return `${optionsHtml}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Processor to generate a list
|
||||||
|
function generateList(data) {
|
||||||
|
var listHtml = "";
|
||||||
|
data.forEach(function(item) {
|
||||||
|
listHtml += `<li>${item.name}</li>`;
|
||||||
|
});
|
||||||
|
listHtml += "";
|
||||||
|
return listHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// initialize
|
// initialize
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
1
front/lib/AdminLTE/bower_components/datatables.net/css/select.dataTables.min.css
vendored
Executable file
1
front/lib/AdminLTE/bower_components/datatables.net/css/select.dataTables.min.css
vendored
Executable file
@@ -0,0 +1 @@
|
|||||||
|
table.dataTable tbody>tr.selected,table.dataTable tbody>tr>.selected{background-color:#b0bed9}table.dataTable.stripe tbody>tr.odd.selected,table.dataTable.stripe tbody>tr.odd>.selected,table.dataTable.display tbody>tr.odd.selected,table.dataTable.display tbody>tr.odd>.selected{background-color:#acbad4}table.dataTable.hover tbody>tr.selected:hover,table.dataTable.hover tbody>tr>.selected:hover,table.dataTable.display tbody>tr.selected:hover,table.dataTable.display tbody>tr>.selected:hover{background-color:#aab7d1}table.dataTable.order-column tbody>tr.selected>.sorting_1,table.dataTable.order-column tbody>tr.selected>.sorting_2,table.dataTable.order-column tbody>tr.selected>.sorting_3,table.dataTable.order-column tbody>tr>.selected,table.dataTable.display tbody>tr.selected>.sorting_1,table.dataTable.display tbody>tr.selected>.sorting_2,table.dataTable.display tbody>tr.selected>.sorting_3,table.dataTable.display tbody>tr>.selected{background-color:#acbad5}table.dataTable.display tbody>tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody>tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody>tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody>tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody>tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody>tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody>tr.odd>.selected,table.dataTable.order-column.stripe tbody>tr.odd>.selected{background-color:#a6b4cd}table.dataTable.display tbody>tr.even>.selected,table.dataTable.order-column.stripe tbody>tr.even>.selected{background-color:#acbad5}table.dataTable.display tbody>tr.selected:hover>.sorting_1,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody>tr.selected:hover>.sorting_2,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody>tr.selected:hover>.sorting_3,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_3{background-color:#a5b2cb}table.dataTable.display tbody>tr:hover>.selected,table.dataTable.display tbody>tr>.selected:hover,table.dataTable.order-column.hover tbody>tr:hover>.selected,table.dataTable.order-column.hover tbody>tr>.selected:hover{background-color:#a2aec7}table.dataTable tbody td.select-checkbox,table.dataTable tbody th.select-checkbox{position:relative}table.dataTable tbody td.select-checkbox:before,table.dataTable tbody td.select-checkbox:after,table.dataTable tbody th.select-checkbox:before,table.dataTable tbody th.select-checkbox:after{display:block;position:absolute;top:1.2em;left:50%;width:12px;height:12px;box-sizing:border-box}table.dataTable tbody td.select-checkbox:before,table.dataTable tbody th.select-checkbox:before{content:" ";margin-top:-6px;margin-left:-6px;border:1px solid black;border-radius:3px}table.dataTable tr.selected td.select-checkbox:after,table.dataTable tr.selected th.select-checkbox:after{content:"✓";font-size:20px;margin-top:-19px;margin-left:-6px;text-align:center;text-shadow:1px 1px #b0bed9,-1px -1px #b0bed9,1px -1px #b0bed9,-1px 1px #b0bed9}table.dataTable.compact tbody td.select-checkbox:before,table.dataTable.compact tbody th.select-checkbox:before{margin-top:-12px}table.dataTable.compact tr.selected td.select-checkbox:after,table.dataTable.compact tr.selected th.select-checkbox:after{margin-top:-16px}div.dataTables_wrapper span.select-info,div.dataTables_wrapper span.select-item{margin-left:.5em}@media screen and (max-width: 640px){div.dataTables_wrapper span.select-info,div.dataTables_wrapper span.select-item{margin-left:0;display:block}}
|
||||||
38
front/lib/AdminLTE/bower_components/datatables.net/js/dataTables.select.min.js
vendored
Executable file
38
front/lib/AdminLTE/bower_components/datatables.net/js/dataTables.select.min.js
vendored
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
/*!
|
||||||
|
Copyright 2015-2021 SpryMedia Ltd.
|
||||||
|
|
||||||
|
This source file is free software, available under the following license:
|
||||||
|
MIT license - http://datatables.net/license/mit
|
||||||
|
|
||||||
|
This source file is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
||||||
|
|
||||||
|
For details please refer to: http://www.datatables.net/extensions/select
|
||||||
|
Select for DataTables 1.3.3
|
||||||
|
2015-2021 SpryMedia Ltd - datatables.net/license/mit
|
||||||
|
*/
|
||||||
|
(function(h){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(q){return h(q,window,document)}):"object"===typeof exports?module.exports=function(q,t){q||(q=window);t&&t.fn.dataTable||(t=require("datatables.net")(q,t).$);return h(t,q,q.document)}:h(jQuery,window,document)})(function(h,q,t,n){function E(a,b,c){var d=function(g,f){if(g>f){var k=f;f=g;g=k}var l=!1;return a.columns(":visible").indexes().filter(function(p){p===g&&(l=!0);return p===f?(l=!1,!0):l})};var e=
|
||||||
|
function(g,f){var k=a.rows({search:"applied"}).indexes();if(k.indexOf(g)>k.indexOf(f)){var l=f;f=g;g=l}var p=!1;return k.filter(function(u){u===g&&(p=!0);return u===f?(p=!1,!0):p})};a.cells({selected:!0}).any()||c?(d=d(c.column,b.column),c=e(c.row,b.row)):(d=d(0,b.column),c=e(0,b.row));c=a.cells(c,d).flatten();a.cells(b,{selected:!0}).any()?a.cells(c).deselect():a.cells(c).select()}function A(a){var b=a.settings()[0]._select.selector;h(a.table().container()).off("mousedown.dtSelect",b).off("mouseup.dtSelect",
|
||||||
|
b).off("click.dtSelect",b);h("body").off("click.dtSelect"+a.table().node().id.replace(/[^a-zA-Z0-9\-_]/g,"-"))}function F(a){var b=h(a.table().container()),c=a.settings()[0],d=c._select.selector,e;b.on("mousedown.dtSelect",d,function(g){if(g.shiftKey||g.metaKey||g.ctrlKey)b.css("-moz-user-select","none").one("selectstart.dtSelect",d,function(){return!1});q.getSelection&&(e=q.getSelection())}).on("mouseup.dtSelect",d,function(){b.css("-moz-user-select","")}).on("click.dtSelect",d,function(g){var f=
|
||||||
|
a.select.items();if(e){var k=q.getSelection();if((!k.anchorNode||h(k.anchorNode).closest("table")[0]===a.table().node())&&k!==e)return}k=a.settings()[0];var l=a.settings()[0].oClasses.sWrapper.trim().replace(/ +/g,".");if(h(g.target).closest("div."+l)[0]==a.table().container()&&(l=a.cell(h(g.target).closest("td, th")),l.any())){var p=h.Event("user-select.dt");r(a,p,[f,l,g]);p.isDefaultPrevented()||(p=l.index(),"row"===f?(f=p.row,B(g,a,k,"row",f)):"column"===f?(f=l.index().column,B(g,a,k,"column",
|
||||||
|
f)):"cell"===f&&(f=l.index(),B(g,a,k,"cell",f)),k._select_lastCell=p)}});h("body").on("click.dtSelect"+a.table().node().id.replace(/[^a-zA-Z0-9\-_]/g,"-"),function(g){!c._select.blurable||h(g.target).parents().filter(a.table().container()).length||0===h(g.target).parents("html").length||h(g.target).parents("div.DTE").length||x(c,!0)})}function r(a,b,c,d){if(!d||a.flatten().length)"string"===typeof b&&(b+=".dt"),c.unshift(a),h(a.table().node()).trigger(b,c)}function I(a){var b=a.settings()[0];if(b._select.info&&
|
||||||
|
b.aanFeatures.i&&"api"!==a.select.style()){var c=a.rows({selected:!0}).flatten().length,d=a.columns({selected:!0}).flatten().length,e=a.cells({selected:!0}).flatten().length,g=function(f,k,l){f.append(h('<span class="select-item"/>').append(a.i18n("select."+k+"s",{_:"%d "+k+"s selected",0:"",1:"1 "+k+" selected"},l)))};h.each(b.aanFeatures.i,function(f,k){k=h(k);f=h('<span class="select-info"/>');g(f,"row",c);g(f,"column",d);g(f,"cell",e);var l=k.children("span.select-info");l.length&&l.remove();
|
||||||
|
""!==f.text()&&k.append(f)})}}function J(a){var b=new m.Api(a);a.aoRowCreatedCallback.push({fn:function(c,d,e){d=a.aoData[e];d._select_selected&&h(c).addClass(a._select.className);c=0;for(e=a.aoColumns.length;c<e;c++)(a.aoColumns[c]._select_selected||d._selected_cells&&d._selected_cells[c])&&h(d.anCells[c]).addClass(a._select.className)},sName:"select-deferRender"});b.on("preXhr.dt.dtSelect",function(c,d){if(d===b.settings()[0]){var e=b.rows({selected:!0}).ids(!0).filter(function(f){return f!==n}),
|
||||||
|
g=b.cells({selected:!0}).eq(0).map(function(f){var k=b.row(f.row).id(!0);return k?{row:k,column:f.column}:n}).filter(function(f){return f!==n});b.one("draw.dt.dtSelect",function(){b.rows(e).select();g.any()&&g.each(function(f){b.cells(f.row,f.column).select()})})}});b.on("draw.dtSelect.dt select.dtSelect.dt deselect.dtSelect.dt info.dt",function(){I(b)});b.on("destroy.dtSelect",function(){b.rows({selected:!0}).deselect();A(b);b.off(".dtSelect")})}function G(a,b,c,d){var e=a[b+"s"]({search:"applied"}).indexes();
|
||||||
|
d=h.inArray(d,e);var g=h.inArray(c,e);if(a[b+"s"]({selected:!0}).any()||-1!==d){if(d>g){var f=g;g=d;d=f}e.splice(g+1,e.length);e.splice(0,d)}else e.splice(h.inArray(c,e)+1,e.length);a[b](c,{selected:!0}).any()?(e.splice(h.inArray(c,e),1),a[b+"s"](e).deselect()):a[b+"s"](e).select()}function x(a,b){if(b||"single"===a._select.style)a=new m.Api(a),a.rows({selected:!0}).deselect(),a.columns({selected:!0}).deselect(),a.cells({selected:!0}).deselect()}function B(a,b,c,d,e){var g=b.select.style(),f=b.select.toggleable(),
|
||||||
|
k=b[d](e,{selected:!0}).any();if(!k||f)"os"===g?a.ctrlKey||a.metaKey?b[d](e).select(!k):a.shiftKey?"cell"===d?E(b,e,c._select_lastCell||null):G(b,d,e,c._select_lastCell?c._select_lastCell[d]:null):(a=b[d+"s"]({selected:!0}),k&&1===a.flatten().length?b[d](e).deselect():(a.deselect(),b[d](e).select())):"multi+shift"==g?a.shiftKey?"cell"===d?E(b,e,c._select_lastCell||null):G(b,d,e,c._select_lastCell?c._select_lastCell[d]:null):b[d](e).select(!k):b[d](e).select(!k)}function y(a,b){return function(c){return c.i18n("buttons."+
|
||||||
|
a,b)}}function C(a){a=a._eventNamespace;return"draw.dt.DT"+a+" select.dt.DT"+a+" deselect.dt.DT"+a}function K(a,b){return-1!==h.inArray("rows",b.limitTo)&&a.rows({selected:!0}).any()||-1!==h.inArray("columns",b.limitTo)&&a.columns({selected:!0}).any()||-1!==h.inArray("cells",b.limitTo)&&a.cells({selected:!0}).any()?!0:!1}var m=h.fn.dataTable;m.select={};m.select.version="1.3.3";m.select.init=function(a){var b=a.settings()[0],c=b.oInit.select,d=m.defaults.select;c=c===n?d:c;d="row";var e="api",g=!1,
|
||||||
|
f=!0,k=!0,l="td, th",p="selected",u=!1;b._select={};!0===c?(e="os",u=!0):"string"===typeof c?(e=c,u=!0):h.isPlainObject(c)&&(c.blurable!==n&&(g=c.blurable),c.toggleable!==n&&(f=c.toggleable),c.info!==n&&(k=c.info),c.items!==n&&(d=c.items),e=c.style!==n?c.style:"os",u=!0,c.selector!==n&&(l=c.selector),c.className!==n&&(p=c.className));a.select.selector(l);a.select.items(d);a.select.style(e);a.select.blurable(g);a.select.toggleable(f);a.select.info(k);b._select.className=p;h.fn.dataTable.ext.order["select-checkbox"]=
|
||||||
|
function(z,L){return this.api().column(L,{order:"index"}).nodes().map(function(H){return"row"===z._select.items?h(H).parent().hasClass(z._select.className):"cell"===z._select.items?h(H).hasClass(z._select.className):!1})};!u&&h(a.table().node()).hasClass("selectable")&&a.select.style("os")};h.each([{type:"row",prop:"aoData"},{type:"column",prop:"aoColumns"}],function(a,b){m.ext.selector[b.type].push(function(c,d,e){d=d.selected;var g=[];if(!0!==d&&!1!==d)return e;for(var f=0,k=e.length;f<k;f++){var l=
|
||||||
|
c[b.prop][e[f]];(!0===d&&!0===l._select_selected||!1===d&&!l._select_selected)&&g.push(e[f])}return g})});m.ext.selector.cell.push(function(a,b,c){b=b.selected;var d=[];if(b===n)return c;for(var e=0,g=c.length;e<g;e++){var f=a.aoData[c[e].row];(!0===b&&f._selected_cells&&!0===f._selected_cells[c[e].column]||!(!1!==b||f._selected_cells&&f._selected_cells[c[e].column]))&&d.push(c[e])}return d});var v=m.Api.register,w=m.Api.registerPlural;v("select()",function(){return this.iterator("table",function(a){m.select.init(new m.Api(a))})});
|
||||||
|
v("select.blurable()",function(a){return a===n?this.context[0]._select.blurable:this.iterator("table",function(b){b._select.blurable=a})});v("select.toggleable()",function(a){return a===n?this.context[0]._select.toggleable:this.iterator("table",function(b){b._select.toggleable=a})});v("select.info()",function(a){return a===n?this.context[0]._select.info:this.iterator("table",function(b){b._select.info=a})});v("select.items()",function(a){return a===n?this.context[0]._select.items:this.iterator("table",
|
||||||
|
function(b){b._select.items=a;r(new m.Api(b),"selectItems",[a])})});v("select.style()",function(a){return a===n?this.context[0]._select.style:this.iterator("table",function(b){b._select.style=a;b._select_init||J(b);var c=new m.Api(b);A(c);"api"!==a&&F(c);r(new m.Api(b),"selectStyle",[a])})});v("select.selector()",function(a){return a===n?this.context[0]._select.selector:this.iterator("table",function(b){A(new m.Api(b));b._select.selector=a;"api"!==b._select.style&&F(new m.Api(b))})});w("rows().select()",
|
||||||
|
"row().select()",function(a){var b=this;if(!1===a)return this.deselect();this.iterator("row",function(c,d){x(c);c.aoData[d]._select_selected=!0;h(c.aoData[d].nTr).addClass(c._select.className)});this.iterator("table",function(c,d){r(b,"select",["row",b[d]],!0)});return this});w("columns().select()","column().select()",function(a){var b=this;if(!1===a)return this.deselect();this.iterator("column",function(c,d){x(c);c.aoColumns[d]._select_selected=!0;d=(new m.Api(c)).column(d);h(d.header()).addClass(c._select.className);
|
||||||
|
h(d.footer()).addClass(c._select.className);d.nodes().to$().addClass(c._select.className)});this.iterator("table",function(c,d){r(b,"select",["column",b[d]],!0)});return this});w("cells().select()","cell().select()",function(a){var b=this;if(!1===a)return this.deselect();this.iterator("cell",function(c,d,e){x(c);d=c.aoData[d];d._selected_cells===n&&(d._selected_cells=[]);d._selected_cells[e]=!0;d.anCells&&h(d.anCells[e]).addClass(c._select.className)});this.iterator("table",function(c,d){r(b,"select",
|
||||||
|
["cell",b.cells(b[d]).indexes().toArray()],!0)});return this});w("rows().deselect()","row().deselect()",function(){var a=this;this.iterator("row",function(b,c){b.aoData[c]._select_selected=!1;b._select_lastCell=null;h(b.aoData[c].nTr).removeClass(b._select.className)});this.iterator("table",function(b,c){r(a,"deselect",["row",a[c]],!0)});return this});w("columns().deselect()","column().deselect()",function(){var a=this;this.iterator("column",function(b,c){b.aoColumns[c]._select_selected=!1;var d=
|
||||||
|
new m.Api(b),e=d.column(c);h(e.header()).removeClass(b._select.className);h(e.footer()).removeClass(b._select.className);d.cells(null,c).indexes().each(function(g){var f=b.aoData[g.row],k=f._selected_cells;!f.anCells||k&&k[g.column]||h(f.anCells[g.column]).removeClass(b._select.className)})});this.iterator("table",function(b,c){r(a,"deselect",["column",a[c]],!0)});return this});w("cells().deselect()","cell().deselect()",function(){var a=this;this.iterator("cell",function(b,c,d){c=b.aoData[c];c._selected_cells[d]=
|
||||||
|
!1;c.anCells&&!b.aoColumns[d]._select_selected&&h(c.anCells[d]).removeClass(b._select.className)});this.iterator("table",function(b,c){r(a,"deselect",["cell",a[c]],!0)});return this});var D=0;h.extend(m.ext.buttons,{selected:{text:y("selected","Selected"),className:"buttons-selected",limitTo:["rows","columns","cells"],init:function(a,b,c){var d=this;c._eventNamespace=".select"+D++;a.on(C(c),function(){d.enable(K(a,c))});this.disable()},destroy:function(a,b,c){a.off(c._eventNamespace)}},selectedSingle:{text:y("selectedSingle",
|
||||||
|
"Selected single"),className:"buttons-selected-single",init:function(a,b,c){var d=this;c._eventNamespace=".select"+D++;a.on(C(c),function(){var e=a.rows({selected:!0}).flatten().length+a.columns({selected:!0}).flatten().length+a.cells({selected:!0}).flatten().length;d.enable(1===e)});this.disable()},destroy:function(a,b,c){a.off(c._eventNamespace)}},selectAll:{text:y("selectAll","Select all"),className:"buttons-select-all",action:function(){this[this.select.items()+"s"]().select()}},selectNone:{text:y("selectNone",
|
||||||
|
"Deselect all"),className:"buttons-select-none",action:function(){x(this.settings()[0],!0)},init:function(a,b,c){var d=this;c._eventNamespace=".select"+D++;a.on(C(c),function(){var e=a.rows({selected:!0}).flatten().length+a.columns({selected:!0}).flatten().length+a.cells({selected:!0}).flatten().length;d.enable(0<e)});this.disable()},destroy:function(a,b,c){a.off(c._eventNamespace)}}});h.each(["Row","Column","Cell"],function(a,b){var c=b.toLowerCase();m.ext.buttons["select"+b+"s"]={text:y("select"+
|
||||||
|
b+"s","Select "+c+"s"),className:"buttons-select-"+c+"s",action:function(){this.select.items(c)},init:function(d){var e=this;d.on("selectItems.dt.DT",function(g,f,k){e.active(k===c)})}}});h(t).on("preInit.dt.dtSelect",function(a,b){"dt"===a.namespace&&m.select.init(new m.Api(b))});return m.select});
|
||||||
@@ -784,6 +784,13 @@ function performLogManage() {
|
|||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
function scrollDown()
|
function scrollDown()
|
||||||
{
|
{
|
||||||
|
var anchor = getUrlAnchor()
|
||||||
|
|
||||||
|
|
||||||
|
if (anchor == "tab_Logging")
|
||||||
|
{
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
var areaIDs = ['pialert_log', 'pialert_front_log', 'IP_changes_log', 'stdout_log', 'stderr_log', 'pialert_pholus_log', 'pialert_pholus_lastrun_log', 'pialert_php_log'];
|
var areaIDs = ['pialert_log', 'pialert_front_log', 'IP_changes_log', 'stdout_log', 'stderr_log', 'pialert_pholus_log', 'pialert_pholus_lastrun_log', 'pialert_php_log'];
|
||||||
|
|
||||||
for (let i = 0; i < areaIDs.length; i++) {
|
for (let i = 0; i < areaIDs.length; i++) {
|
||||||
@@ -796,6 +803,10 @@ function scrollDown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}, 55);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
@@ -900,12 +911,6 @@ function initializeTabs () {
|
|||||||
// events on tab change
|
// events on tab change
|
||||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||||
var target = $(e.target).attr("href") // activated tab
|
var target = $(e.target).attr("href") // activated tab
|
||||||
|
|
||||||
// scroll to the latest log entrie sat teh bottom of the file
|
|
||||||
if(target == "#tab_Logging")
|
|
||||||
{
|
|
||||||
scrollDown();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}, 50);
|
}, 50);
|
||||||
@@ -918,17 +923,20 @@ window.onload = function asyncFooter()
|
|||||||
{
|
{
|
||||||
initializeSelectedColumns();
|
initializeSelectedColumns();
|
||||||
|
|
||||||
scrollDown();
|
|
||||||
|
|
||||||
initializeTabs();
|
initializeTabs();
|
||||||
|
|
||||||
$("#lastCommit").append('<a href="https://github.com/jokob-sk/Pi.Alert/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/pi.alert/main?logo=github"></a>');
|
$("#lastCommit").append('<a href="https://github.com/jokob-sk/Pi.Alert/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/pi.alert/main?logo=github"></a>');
|
||||||
|
|
||||||
$("#lastDockerUpdate").append(
|
$("#lastDockerUpdate").append(
|
||||||
'<a href="https://hub.docker.com/r/jokobsk/pi.alert/tags" target="_blank"><img alt="Docker last pushed" src="https://img.shields.io/badge/dynamic/json?color=blue&label=Last%20pushed&query=last_updated&url=https%3A%2F%2Fhub.docker.com%2Fv2%2Frepositories%2Fjokobsk%2Fpi.alert%2F&logo=docker&?link=http://left&link=https://hub.docker.com/repository/docker/jokobsk/pi.alert"></a>');
|
'<a href="https://github.com/jokob-sk/Pi.Alert/releases" target="_blank"><img alt="Docker last pushed" src="https://img.shields.io/github/v/release/jokob-sk/Pi.Alert?color=0aa8d2&logoColor=fff&logo=GitHub&label=Latest"></a>');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scroll to the latest log entrie sat teh bottom of the file
|
||||||
|
|
||||||
|
scrollDown();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="lib/AdminLTE/bower_components/select2/dist/css/select2.min.css">
|
<link rel="stylesheet" href="lib/AdminLTE/bower_components/select2/dist/css/select2.min.css">
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="box box-default">
|
<div class="box box-default">
|
||||||
|
|
||||||
@@ -65,7 +67,7 @@
|
|||||||
|
|
||||||
settingsData = res["data"];
|
settingsData = res["data"];
|
||||||
|
|
||||||
excludedColumns = ["NEWDEV_dev_MAC", "NEWDEV_dev_FirstConnection", "NEWDEV_dev_LastConnection", "dev_LastNotification", "NEWDEV_dev_LastIP", "NEWDEV_dev_StaticIP", "NEWDEV_dev_ScanCycle", "NEWDEV_dev_PresentLastScan" ]
|
excludedColumns = ["NEWDEV_dev_MAC", "NEWDEV_dev_FirstConnection", "NEWDEV_dev_LastConnection", "NEWDEV_dev_LastNotification", "NEWDEV_dev_LastIP", "NEWDEV_dev_StaticIP", "NEWDEV_dev_ScanCycle", "NEWDEV_dev_PresentLastScan" ]
|
||||||
|
|
||||||
const relevantColumns = settingsData.filter(set =>
|
const relevantColumns = settingsData.filter(set =>
|
||||||
set.Group === "NEWDEV" &&
|
set.Group === "NEWDEV" &&
|
||||||
@@ -88,21 +90,53 @@
|
|||||||
// 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 inputType = columns[j].Type === 'integer.checkbox' ? 'checkbox' : 'text';
|
let inputType;
|
||||||
|
|
||||||
|
switch (columns[j].Type) {
|
||||||
|
case 'integer.checkbox':
|
||||||
|
case 'checkbox':
|
||||||
|
inputType = 'checkbox';
|
||||||
|
break;
|
||||||
|
case 'text.select':
|
||||||
|
inputType = 'text.select';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
inputType = 'text';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Add classes specifically for checkboxes
|
// Add classes specifically for checkboxes
|
||||||
|
if (inputType === 'text.select') {
|
||||||
|
|
||||||
|
targetLocation = columns[j].Code_Name + "_initSettingDropdown"
|
||||||
|
|
||||||
|
initSettingDropdown(columns[j].Code_Name, targetLocation)
|
||||||
|
|
||||||
|
input = `<select>
|
||||||
|
<option id="${targetLocation}"></option>
|
||||||
|
</select>`
|
||||||
|
} else {
|
||||||
|
|
||||||
if (inputType === 'checkbox') {
|
if (inputType === 'checkbox') {
|
||||||
inputClass = 'checkbox';
|
inputClass = 'checkbox';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
inputClass = 'form-control';
|
inputClass = 'form-control';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input = `<input class="${inputClass}"
|
||||||
|
id="${columns[j].Code_Name}"
|
||||||
|
data-my-column="${columns[j].Code_Name}"
|
||||||
|
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}"
|
||||||
|
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].Display_Name}</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 class="${inputClass}" id="${columns[j].Code_Name}" data-my-column="${columns[j].Code_Name}" data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" type="${inputType}">
|
${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].Code_Name}');" title="${getString('Device_MultiEdit_Tooltip')}">
|
||||||
<i class="fa fa-save"></i>
|
<i class="fa fa-save"></i>
|
||||||
</span>
|
</span>
|
||||||
@@ -118,6 +152,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(relevantColumns)
|
||||||
|
|
||||||
generateSimpleForm(relevantColumns);
|
generateSimpleForm(relevantColumns);
|
||||||
|
|
||||||
@@ -220,3 +255,4 @@ getData();
|
|||||||
|
|
||||||
<!-- ----------------------------------------------------------------------- -->
|
<!-- ----------------------------------------------------------------------- -->
|
||||||
<script src="js/ui_components.js"></script>
|
<script src="js/ui_components.js"></script>
|
||||||
|
<script src="js/db_methods.js"></script>
|
||||||
@@ -56,6 +56,10 @@
|
|||||||
$columns = $_REQUEST['columns'];
|
$columns = $_REQUEST['columns'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset ($_REQUEST['rawSql'])) {
|
||||||
|
$rawSql = $_REQUEST['rawSql'];
|
||||||
|
}
|
||||||
|
|
||||||
if (isset ($_REQUEST['dbtable'])) {
|
if (isset ($_REQUEST['dbtable'])) {
|
||||||
$dbtable = $_REQUEST['dbtable'];
|
$dbtable = $_REQUEST['dbtable'];
|
||||||
}
|
}
|
||||||
@@ -64,19 +68,56 @@
|
|||||||
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
|
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
|
||||||
$action = $_REQUEST['action'];
|
$action = $_REQUEST['action'];
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'create': create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values ); break;
|
case 'create': create($defaultValue, $expireMinutes, $dbtable, $columns, $values ); break;
|
||||||
// case 'read' : read($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break;
|
case 'read' : read($rawSql); break;
|
||||||
case 'update': update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break;
|
case 'update': update($columnName, $id, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break;
|
||||||
case 'delete': delete($columnName, $id, $dbtable); break;
|
case 'delete': delete($columnName, $id, $dbtable); break;
|
||||||
default: logServerConsole ('Action: '. $action); break;
|
default: logServerConsole ('Action: '. $action); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// read
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
function read($rawSql) {
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
// Construct the SQL query to select values
|
||||||
|
$sql = $rawSql;
|
||||||
|
|
||||||
|
// Execute the SQL query
|
||||||
|
$result = $db->query($sql);
|
||||||
|
|
||||||
|
// Check if the query executed successfully
|
||||||
|
if (! $result == TRUE) {
|
||||||
|
// Output an error message if the query failed
|
||||||
|
echo "Error reading data\n\n " .$sql." \n\n". $db->lastErrorMsg();
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// Output $result
|
||||||
|
// Fetching rows from the result object and storing them in an array
|
||||||
|
$rows = array();
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$rows[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converting the array to JSON
|
||||||
|
$json = json_encode($rows);
|
||||||
|
|
||||||
|
// Outputting the JSON
|
||||||
|
echo $json;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// update
|
// update
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values) {
|
function update($columnName, $id, $defaultValue, $expireMinutes, $dbtable, $columns, $values) {
|
||||||
|
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
@@ -138,7 +179,7 @@ function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $db
|
|||||||
$changes = $db->changes();
|
$changes = $db->changes();
|
||||||
if ($changes == 0) {
|
if ($changes == 0) {
|
||||||
// Insert new value
|
// Insert new value
|
||||||
create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values);
|
create( $defaultValue, $expireMinutes, $dbtable, $columns, $values);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
@@ -152,7 +193,7 @@ function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $db
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// create
|
// create
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
function create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values)
|
function create( $defaultValue, $expireMinutes, $dbtable, $columns, $values)
|
||||||
{
|
{
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
@@ -211,7 +252,7 @@ function delete($columnName, $id, $dbtable)
|
|||||||
// Check if the query executed successfully
|
// Check if the query executed successfully
|
||||||
if (! $result == TRUE) {
|
if (! $result == TRUE) {
|
||||||
// Output an error message if the query failed
|
// Output an error message if the query failed
|
||||||
echo "Error deleting entry\n\n$sql \n\n". $db->lastErrorMsg();
|
echo "Error deleting entry\n\n".$sql." \n\n". $db->lastErrorMsg();
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ if ($ENABLED_DARKMODE === True) {
|
|||||||
</a>
|
</a>
|
||||||
<ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
<ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||||
<li>
|
<li>
|
||||||
<a href="maintenance.php#tab_Settings" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_Settings");?> </a>
|
<a href="maintenance.php#tab_Settings" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_UISettings");?> </a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="maintenance.php#tab_DBTools" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_Tools");?> </a>
|
<a href="maintenance.php#tab_DBTools" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_Tools");?> </a>
|
||||||
|
|||||||
0
front/php/templates/language/es_es.json
Normal file → Executable file
0
front/php/templates/language/es_es.json
Normal file → Executable file
@@ -648,6 +648,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
|||||||
| See below for information on `threshold`, `replace`. | |
|
| See below for information on `threshold`, `replace`. | |
|
||||||
| | |
|
| | |
|
||||||
| `options` Property | Used in conjunction with types like `threshold`, `replace`, `regex`. |
|
| `options` Property | Used in conjunction with types like `threshold`, `replace`, `regex`. |
|
||||||
|
| `options_params` Property | Used in conjunction with a `"default_value": "{value}"` template and `text.select`. Can specify SQL query or Setting to populate the dropdown. Check example below. |
|
||||||
| `threshold` | The `options` array contains objects ordered from the lowest `maximum` to the highest. The corresponding `hexColor` is used for the value background color if it's less than the specified `maximum` but more than the previous one in the `options` array. |
|
| `threshold` | The `options` array contains objects ordered from the lowest `maximum` to the highest. The corresponding `hexColor` is used for the value background color if it's less than the specified `maximum` but more than the previous one in the `options` array. |
|
||||||
| `replace` | The `options` array contains objects with an `equals` property, which is compared to the "value." If the values are the same, the string in `replacement` is displayed in the UI instead of the actual "value". |
|
| `replace` | The `options` array contains objects with an `equals` property, which is compared to the "value." If the values are the same, the string in `replacement` is displayed in the UI instead of the actual "value". |
|
||||||
| `regex` | Applies a regex to the value. The `options` array contains objects with an `type` (must be set to `regex`) and `param` (must contain the regex itself) property. |
|
| `regex` | Applies a regex to the value. The `options` array contains objects with an `type` (must be set to `regex`) and `param` (must contain the regex itself) property. |
|
||||||
@@ -666,6 +667,21 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
|||||||
> Supports chaining. You can chain multiple resolvers with `.`. For example `regex.url_http_https`. This will apply the `regex` resolver and then the `url_http_https` resolver.
|
> Supports chaining. You can chain multiple resolvers with `.`. For example `regex.url_http_https`. This will apply the `regex` resolver and then the `url_http_https` resolver.
|
||||||
|
|
||||||
|
|
||||||
|
```json
|
||||||
|
"options_params" : [
|
||||||
|
{
|
||||||
|
"name" : "value",
|
||||||
|
"type" : "sql",
|
||||||
|
"value" : "SELECT Dev_Name as name, dev_MAC as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(dev_DeviceType) || '%' AND dev_DeviceType <> '')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "target_macs",
|
||||||
|
"type" : "setting",
|
||||||
|
"value" : "KNWN_target_macs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ def publish_sensor(mqtt_client, sensorConfig):
|
|||||||
|
|
||||||
global mqtt_sensors
|
global mqtt_sensors
|
||||||
|
|
||||||
|
icon = "mdi:" + sensorConfig.icon
|
||||||
|
|
||||||
message = {
|
message = {
|
||||||
"name" : sensorConfig.sensorName,
|
"name" : sensorConfig.sensorName,
|
||||||
"state_topic" : "system-sensors/"+sensorConfig.sensorType+'/'+sensorConfig.deviceId+"/state",
|
"state_topic" : "system-sensors/"+sensorConfig.sensorType+'/'+sensorConfig.deviceId+"/state",
|
||||||
@@ -215,7 +217,7 @@ def publish_sensor(mqtt_client, sensorConfig):
|
|||||||
"manufacturer" : "PiAlert",
|
"manufacturer" : "PiAlert",
|
||||||
"name" : sensorConfig.deviceName
|
"name" : sensorConfig.deviceName
|
||||||
},
|
},
|
||||||
"icon":"mdi:'+sensorConfig.icon+'"
|
"icon": icon
|
||||||
}
|
}
|
||||||
|
|
||||||
topic='homeassistant/'+sensorConfig.sensorType+'/'+sensorConfig.deviceId+'/'+sensorConfig.sensorName+'/config'
|
topic='homeassistant/'+sensorConfig.sensorType+'/'+sensorConfig.deviceId+'/'+sensorConfig.sensorName+'/config'
|
||||||
|
|||||||
@@ -124,10 +124,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"function": "dev_DeviceType",
|
"function": "dev_DeviceType",
|
||||||
"type": "string",
|
"type": "text.select",
|
||||||
"maxLength": 30,
|
"maxLength": 30,
|
||||||
"default_value": "",
|
"default_value": "{value}",
|
||||||
"options": [],
|
"options": [],
|
||||||
|
"options_params" : [
|
||||||
|
{
|
||||||
|
"name" : "value",
|
||||||
|
"type" : "sql",
|
||||||
|
"value" : "SELECT DISTINCT dev_DeviceType as id, dev_DeviceType as name FROM Devices "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "uilang",
|
||||||
|
"type" : "setting",
|
||||||
|
"value" : "UI_LANG"
|
||||||
|
}
|
||||||
|
],
|
||||||
"localized": ["name", "description"],
|
"localized": ["name", "description"],
|
||||||
"name": [
|
"name": [
|
||||||
{
|
{
|
||||||
@@ -492,9 +504,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"function": "dev_Network_Node_MAC_ADDR",
|
"function": "dev_Network_Node_MAC_ADDR",
|
||||||
"type": "string",
|
"type": "text.select",
|
||||||
"default_value": "",
|
"default_value": "{value}",
|
||||||
"options": [],
|
"options": [],
|
||||||
|
"options_params" : [
|
||||||
|
{
|
||||||
|
"name" : "value",
|
||||||
|
"type" : "sql",
|
||||||
|
"value" : "SELECT Dev_Name as name, dev_MAC as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(dev_DeviceType) || '%' AND dev_DeviceType <> '')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "target_macs",
|
||||||
|
"type" : "setting",
|
||||||
|
"value" : "KNWN_target_macs"
|
||||||
|
}
|
||||||
|
],
|
||||||
"localized": ["name", "description"],
|
"localized": ["name", "description"],
|
||||||
"name": [
|
"name": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
|||||||
|
|
||||||
<script src="js/pialert_common.js"></script>
|
<script src="js/pialert_common.js"></script>
|
||||||
<script src="js/settings_utils.js"></script>
|
<script src="js/settings_utils.js"></script>
|
||||||
|
<script src="js/db_methods.js"></script>
|
||||||
|
<script src="js/ui_components.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<div id="settingsPage" class="content-wrapper">
|
<div id="settingsPage" class="content-wrapper">
|
||||||
@@ -394,11 +396,11 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
|||||||
|
|
||||||
if(setType.includes(".select"))
|
if(setType.includes(".select"))
|
||||||
{
|
{
|
||||||
inputHtml = generateInputOptions(set, inputHtml, isMultiSelect = false)
|
inputHtml = generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = false)
|
||||||
|
|
||||||
} else if(setType.includes(".multiselect"))
|
} else if(setType.includes(".multiselect"))
|
||||||
{
|
{
|
||||||
inputHtml = generateInputOptions(set, inputHtml, isMultiSelect = true)
|
inputHtml = generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = true)
|
||||||
} else{
|
} else{
|
||||||
|
|
||||||
// if it's overridable set readonly accordingly
|
// if it's overridable set readonly accordingly
|
||||||
@@ -427,7 +429,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
|||||||
inputHtml = `<input onChange="settingsChanged()" my-data-type="${setType}" class="checkbox" id="${codeName}" type="checkbox" value="${val}" ${checked} ${disabled}/>`;
|
inputHtml = `<input onChange="settingsChanged()" my-data-type="${setType}" class="checkbox" id="${codeName}" type="checkbox" value="${val}" ${checked} ${disabled}/>`;
|
||||||
} else if (setType === 'integer.select') {
|
} else if (setType === 'integer.select') {
|
||||||
|
|
||||||
inputHtml = generateInputOptions(set, inputHtml)
|
inputHtml = generateInputOptions(pluginsData, set, inputHtml)
|
||||||
|
|
||||||
} else if (setType === 'subnets') {
|
} else if (setType === 'subnets') {
|
||||||
inputHtml = `
|
inputHtml = `
|
||||||
@@ -523,25 +525,55 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// generate a list of options for a input select
|
// generate a list of options for a input select
|
||||||
function generateInputOptions(set, input, isMultiSelect = false)
|
function generateInputOptions(pluginsData, set, input, isMultiSelect = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
multi = isMultiSelect ? "multiple" : "";
|
prefix = set["Group"]
|
||||||
input = `<select onChange="settingsChanged()" my-data-type="${set['Type']}" class="form-control" name="${set['Code_Name']}" id="${set['Code_Name']}" ${multi}>`;
|
|
||||||
|
|
||||||
|
var optionsHtml = ""
|
||||||
|
|
||||||
|
multi = isMultiSelect ? "multiple" : "";
|
||||||
|
|
||||||
|
tmpOptions = set['Options']
|
||||||
|
|
||||||
|
setVal = getSetting(set['Code_Name'] )
|
||||||
|
|
||||||
|
// check if the result is a SQL query
|
||||||
|
if(isSQLQuery(setVal))
|
||||||
|
{
|
||||||
|
var targetLocation = set['Code_Name'] + "_initSettingDropdown";
|
||||||
|
|
||||||
|
optionsHtml += `<option id="${targetLocation}"></option>`;
|
||||||
|
|
||||||
|
console.log(set['Code_Name'] )
|
||||||
|
console.log(setVal )
|
||||||
|
|
||||||
|
initSettingDropdown(set['Code_Name'] , targetLocation)
|
||||||
|
|
||||||
|
} else // this should be already an array, e.g. from a setting or pre-defined
|
||||||
|
{
|
||||||
|
options = createArray(tmpOptions);
|
||||||
values = createArray(set['Value']);
|
values = createArray(set['Value']);
|
||||||
options = createArray(set['Options']);
|
|
||||||
|
|
||||||
options.forEach(option => {
|
options.forEach(option => {
|
||||||
let selected = values.includes(option) ? 'selected' : '';
|
let selected = values.includes(option) ? 'selected' : '';
|
||||||
input += `<option value="${option}" ${selected}>${option}</option>`;
|
optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
input += '</select>';
|
}
|
||||||
|
|
||||||
|
input += `
|
||||||
|
<select onChange="settingsChanged()"
|
||||||
|
my-data-type="${set['Type']}"
|
||||||
|
class="form-control"
|
||||||
|
name="${set['Code_Name']}"
|
||||||
|
id="${set['Code_Name']}" ${multi}>
|
||||||
|
${optionsHtml}
|
||||||
|
|
||||||
|
</select>`;
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
@@ -702,10 +734,8 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user