From e38d2f9055eacb2a060e5a4ff47da376f8e0768a Mon Sep 17 00:00:00 2001 From: Jokob-sk Date: Sun, 10 Mar 2024 21:50:04 +1100 Subject: [PATCH] =?UTF-8?q?dynamic=20dropdown=20support=20in=20FE=20-=20co?= =?UTF-8?q?re=20app=20feature=20=F0=9F=92=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- front/devices.php | 6 +- front/js/db_methods.js | 18 +++ front/js/pialert_common.js | 121 ++++++++++++++++-- front/js/settings_utils.js | 7 +- front/js/ui_components.js | 68 ++++++++++ .../css/select.dataTables.min.css | 1 + .../js/dataTables.select.min.js | 38 ++++++ front/maintenance.php | 38 +++--- front/multiEditCore.php | 72 ++++++++--- front/php/server/dbHelper.php | 55 +++++++- front/php/templates/header.php | 2 +- front/php/templates/language/es_es.json | 0 front/plugins/README.md | 16 +++ front/plugins/_publisher_mqtt/mqtt.py | 4 +- front/plugins/newdev_template/config.json | 32 ++++- front/settings.php | 62 ++++++--- 17 files changed, 465 insertions(+), 77 deletions(-) create mode 100755 front/js/db_methods.js create mode 100755 front/lib/AdminLTE/bower_components/datatables.net/css/select.dataTables.min.css create mode 100755 front/lib/AdminLTE/bower_components/datatables.net/js/dataTables.select.min.js mode change 100644 => 100755 front/php/templates/language/es_es.json diff --git a/README.md b/README.md index 411e96df..32bde280 100755 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ This project would be nothing without the amazing work of the community, with sp > [pucherot/Pi.Alert](https://github.com/pucherot/Pi.Alert) (the original creator of PiAlert), [leiweibau](https://github.com/leiweibau/Pi.Alert): Dark mode (and much more), [Macleykun](https://github.com/Macleykun) (Help with Dockerfile clean-up) [Final-Hawk](https://github.com/Final-Hawk) (Help with NTFY, styling and other fixes), [TeroRERO](https://github.com/terorero) (Spanish translations), [Data-Monkey](https://github.com/Data-Monkey), (Split-up of the python.py file and more), [cvc90](https://github.com/cvc90) (Spanish translation and various UI work) to name a few... -Here is every one that helped and contributed to this project: +Here is everyone that helped and contributed to this project: diff --git a/front/devices.php b/front/devices.php index a3c8acce..329cbf97 100755 --- a/front/devices.php +++ b/front/devices.php @@ -189,12 +189,10 @@ + - - - - + diff --git a/front/multiEditCore.php b/front/multiEditCore.php index 58af3edd..3036b442 100755 --- a/front/multiEditCore.php +++ b/front/multiEditCore.php @@ -1,3 +1,5 @@ + +
@@ -65,7 +67,7 @@ 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 => set.Group === "NEWDEV" && @@ -88,36 +90,69 @@ // Append form groups to the column 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 + if (inputType === 'text.select') { + + targetLocation = columns[j].Code_Name + "_initSettingDropdown" + + initSettingDropdown(columns[j].Code_Name, targetLocation) + + input = `` + } else { - // Add classes specifically for checkboxes if (inputType === 'checkbox') { - inputClass = 'checkbox'; + inputClass = 'checkbox'; + } else { - inputClass = 'form-control'; + inputClass = 'form-control'; } + input = `` + } - const inputEntry = `
- -
-
- - - - -
+ + const inputEntry = `
+ +
+
+ ${input} + + +
-
` +
+
` - - column.append(inputEntry); + + column.append(inputEntry); } form.append(column); } }; + console.log(relevantColumns) generateSimpleForm(relevantColumns); @@ -219,4 +254,5 @@ getData(); - \ No newline at end of file + + \ No newline at end of file diff --git a/front/php/server/dbHelper.php b/front/php/server/dbHelper.php index f55b01b6..539dee3d 100755 --- a/front/php/server/dbHelper.php +++ b/front/php/server/dbHelper.php @@ -56,6 +56,10 @@ $columns = $_REQUEST['columns']; } + if (isset ($_REQUEST['rawSql'])) { + $rawSql = $_REQUEST['rawSql']; + } + if (isset ($_REQUEST['dbtable'])) { $dbtable = $_REQUEST['dbtable']; } @@ -64,19 +68,56 @@ if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) { $action = $_REQUEST['action']; switch ($action) { - case 'create': create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values ); break; - // case 'read' : read($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break; - case 'update': update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break; + case 'create': create($defaultValue, $expireMinutes, $dbtable, $columns, $values ); break; + case 'read' : read($rawSql); break; + case 'update': update($columnName, $id, $defaultValue, $expireMinutes, $dbtable, $columns, $values); break; case 'delete': delete($columnName, $id, $dbtable); 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 //------------------------------------------------------------------------------ -function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values) { +function update($columnName, $id, $defaultValue, $expireMinutes, $dbtable, $columns, $values) { global $db; @@ -138,7 +179,7 @@ function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $db $changes = $db->changes(); if ($changes == 0) { // Insert new value - create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values); + create( $defaultValue, $expireMinutes, $dbtable, $columns, $values); } // update cache @@ -152,7 +193,7 @@ function update($columnName, $id, $skipCache, $defaultValue, $expireMinutes, $db //------------------------------------------------------------------------------ // create //------------------------------------------------------------------------------ -function create($skipCache, $defaultValue, $expireMinutes, $dbtable, $columns, $values) +function create( $defaultValue, $expireMinutes, $dbtable, $columns, $values) { global $db; @@ -211,7 +252,7 @@ function delete($columnName, $id, $dbtable) // Check if the query executed successfully if (! $result == TRUE) { // 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; } else { diff --git a/front/php/templates/header.php b/front/php/templates/header.php index a8631185..ffdc4913 100755 --- a/front/php/templates/header.php +++ b/front/php/templates/header.php @@ -294,7 +294,7 @@ if ($ENABLED_DARKMODE === True) {
  • - +
  • diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json old mode 100644 new mode 100755 diff --git a/front/plugins/README.md b/front/plugins/README.md index bdf586b3..42398c12 100755 --- a/front/plugins/README.md +++ b/front/plugins/README.md @@ -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`. | | | | | | `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. | | `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. | @@ -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. +```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 { diff --git a/front/plugins/_publisher_mqtt/mqtt.py b/front/plugins/_publisher_mqtt/mqtt.py index 39a81ed6..9b5382f0 100755 --- a/front/plugins/_publisher_mqtt/mqtt.py +++ b/front/plugins/_publisher_mqtt/mqtt.py @@ -204,6 +204,8 @@ def publish_sensor(mqtt_client, sensorConfig): global mqtt_sensors + icon = "mdi:" + sensorConfig.icon + message = { "name" : sensorConfig.sensorName, "state_topic" : "system-sensors/"+sensorConfig.sensorType+'/'+sensorConfig.deviceId+"/state", @@ -215,7 +217,7 @@ def publish_sensor(mqtt_client, sensorConfig): "manufacturer" : "PiAlert", "name" : sensorConfig.deviceName }, - "icon":"mdi:'+sensorConfig.icon+'" + "icon": icon } topic='homeassistant/'+sensorConfig.sensorType+'/'+sensorConfig.deviceId+'/'+sensorConfig.sensorName+'/config' diff --git a/front/plugins/newdev_template/config.json b/front/plugins/newdev_template/config.json index fa32fe31..e437dd60 100755 --- a/front/plugins/newdev_template/config.json +++ b/front/plugins/newdev_template/config.json @@ -124,10 +124,22 @@ }, { "function": "dev_DeviceType", - "type": "string", + "type": "text.select", "maxLength": 30, - "default_value": "", + "default_value": "{value}", "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"], "name": [ { @@ -492,9 +504,21 @@ }, { "function": "dev_Network_Node_MAC_ADDR", - "type": "string", - "default_value": "", + "type": "text.select", + "default_value": "{value}", "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"], "name": [ { diff --git a/front/settings.php b/front/settings.php index e699b88d..3c4ab28c 100755 --- a/front/settings.php +++ b/front/settings.php @@ -55,6 +55,8 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { + +
    @@ -394,11 +396,11 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { if(setType.includes(".select")) { - inputHtml = generateInputOptions(set, inputHtml, isMultiSelect = false) + inputHtml = generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = false) } else if(setType.includes(".multiselect")) { - inputHtml = generateInputOptions(set, inputHtml, isMultiSelect = true) + inputHtml = generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = true) } else{ // if it's overridable set readonly accordingly @@ -427,7 +429,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { inputHtml = ``; } else if (setType === 'integer.select') { - inputHtml = generateInputOptions(set, inputHtml) + inputHtml = generateInputOptions(pluginsData, set, inputHtml) } else if (setType === 'subnets') { inputHtml = ` @@ -523,26 +525,56 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { } - - // --------------------------------------------------------- // generate a list of options for a input select - function generateInputOptions(set, input, isMultiSelect = false) + function generateInputOptions(pluginsData, set, input, isMultiSelect = false) { + prefix = set["Group"] + + var optionsHtml = "" + multi = isMultiSelect ? "multiple" : ""; - input = `'; + 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']); + + + options.forEach(option => { + let selected = values.includes(option) ? 'selected' : ''; + optionsHtml += ``; + }); + + } + + input += ` + `; + return input; } @@ -702,10 +734,8 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { } }); - }) - } }