diff --git a/front/js/modal.js b/front/js/modal.js
index eb6dfba7..2fb79e71 100755
--- a/front/js/modal.js
+++ b/front/js/modal.js
@@ -167,11 +167,10 @@ function showModalPopupForm(
message,
btnCancel = getString("Gen_Cancel"),
btnOK = getString("Gen_Okay"),
- curValue = "",
- callbackFunction = null,
- triggeredBy = null,
+ curValue = null,
popupFormJson = null,
- parentSettingKey = null
+ parentSettingKey = null,
+ triggeredBy = null
) {
// set captions
prefix = "modal-form";
@@ -182,8 +181,11 @@ function showModalPopupForm(
$(`#${prefix}-cancel`).html(btnCancel);
$(`#${prefix}-OK`).html(btnOK);
- if (triggeredBy != null) {
- $('#'+prefix).attr("data-myparam-triggered-by", triggeredBy)
+ // if curValue not null
+
+ if (curValue)
+ {
+ initialValues = JSON.parse(atob(curValue));
}
outputHtml = "";
@@ -191,17 +193,24 @@ function showModalPopupForm(
if (Array.isArray(popupFormJson)) {
popupFormJson.forEach((field, index) => {
// You'll need to define these or map them from `field`
- const setName = field.name?.find(n => n.language_code === "en_us")?.string || setKey;
+ const setKey = field.function || `field_${index}`;
+ const setName = getString(`${parentSettingKey}_popupform_${setKey}_name`);
const labelClasses = "col-sm-2"; // example, or from your obj.labelClasses
const inputClasses = "col-sm-10"; // example, or from your obj.inputClasses
- const fieldData = field.default_value ?? "";
- const fieldOptionsOverride = field.type?.elements[0]?.elementOptions || [];
+ let initialValue = '';
+ if (curValue && Array.isArray(initialValues)) {
+ const match = initialValues.find(
+ v => v[1] == setKey
+ );
+ if (match) {
+ initialValue = match[3];
+ }
+ }
- const setKey = field.function || `field_${index}`;
- const setValue = field.default_value ?? "";
+ const fieldOptionsOverride = field.type?.elements[0]?.elementOptions || [];
+ const setValue = initialValue;
const setType = JSON.stringify(field.type);
const setEvents = field.events || []; // default to empty array if missing
-
const setObj = { setKey, setValue, setType, setEvents };
// Generate the input field HTML
@@ -218,7 +227,7 @@ function showModalPopupForm(
${generateFormHtml(
null, // settingsData only required for datatables
setObj,
- fieldData.toString(),
+ null,
fieldOptionsOverride,
null
)}
@@ -233,11 +242,6 @@ function showModalPopupForm(
$(`#modal-form-plc`).html(outputHtml);
- // $(`#${prefix}-field`).val(curValue);
- // setTimeout(function () {
- // $(`#${prefix}-field`).focus();
- // }, 500);
-
// Bind OK button click event
$(`#${prefix}-OK`).off("click").on("click", function() {
let settingsArray = [];
@@ -245,13 +249,38 @@ function showModalPopupForm(
popupFormJson.forEach(field => {
collectSetting(
`${parentSettingKey}_popupform`, // prefix
- field.function + '_in', // setCodeName + sourceSuffixes
+ field.function, // setCodeName
field.type, // setType (object)
settingsArray
);
});
}
+ // Encode settings
+ const jsonData = JSON.stringify(settingsArray);
+ const encodedValue = btoa(jsonData);
+
+ // Get label from the FIRST field (value in 4th column)
+ const label = settingsArray[0][3]
+
+ // Add new option to target select
+ const selectId = parentSettingKey;
+
+ // If triggered by an option, update it; otherwise append new
+ if (triggeredBy && $(triggeredBy).is("option")) {
+ // Update existing option
+ $(triggeredBy)
+ .attr("value", encodedValue)
+ .text(label);
+ } else {
+ const newOption = $("")
+ .attr("value", encodedValue)
+ .text(label);
+
+ $("#" + selectId).append(newOption);
+ initListInteractionOptions(newOption);
+ }
+
console.log("Collected popup form settings:", settingsArray);
if (typeof modalCallbackFunction === "function") {
@@ -259,9 +288,7 @@ function showModalPopupForm(
}
$(`#${prefix}`).modal("hide");
-});
-
-
+ });
// Show modal
$(`#${prefix}`).modal("show");
diff --git a/front/js/settings_utils.js b/front/js/settings_utils.js
index f639fb0e..8d604d78 100755
--- a/front/js/settings_utils.js
+++ b/front/js/settings_utils.js
@@ -246,13 +246,6 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) {
// Manipulating Editable List options
// -------------------------------------------------------------------
-// ---------------------------------------------------------
-// Add row to datatable
-function addDataTableRow(el)
-{
- alert("a")
-}
-
// ---------------------------------------------------------
// Clone datatable row
function cloneDataTableRow(el){
@@ -311,42 +304,32 @@ function removeDataTableRow(el) {
// ---------------------------------------------------------
// Add item via pop up form dialog
function addViaPopupForm(element) {
- console.log(element)
+ console.log(element);
- const fromId = $(element).attr("my-input-from");
const toId = $(element).attr("my-input-to");
- const curValue = $(`#${fromId}`).val();
- const triggeredBy = $(element).attr("id");
- const parsed = JSON.parse(atob($(element).data("elementoptionsbase64")));
+ const curValue = $(`#${toId}`).val();
+ const parsed = JSON.parse(atob($(`#${toId}`).data("elementoptionsbase64")));
const popupFormJson = parsed.find(obj => "popupForm" in obj)?.popupForm ?? null;
- console.log(`fromId | toId | triggeredBy | curValue: ${fromId} | ${toId} | ${triggeredBy} | ${curValue}`);
+ console.log(`toId | curValue: ${toId} | ${curValue}`);
showModalPopupForm(
` ${getString(
"Gen_Update_Value"
- )}`, // title
- getString("settings_update_item_warning"), // message
- getString("Gen_Cancel"), // btnCancel
- getString("Gen_Add"), // btnOK
- curValue, // curValue
- null, // callbackFunction
- triggeredBy, // triggeredBy
- popupFormJson, // popupform
- toId // parentSettingKey
+ )}`, // title
+ getString("settings_update_item_warning"), // message
+ getString("Gen_Cancel"), // btnCancel
+ getString("Gen_Add"), // btnOK
+ null, // curValue
+ popupFormJson, // popupform
+ toId, // parentSettingKey
+ element // triggeredBy
);
-}
-
-// ---------------------------------------------------------
-// Add item to list via popup form
-function addViaPopupFormToList(element, clearInput = true) {
-
// flag something changes to prevent navigating from page
settingsChanged();
}
-
// ---------------------------------------------------------
// Add item to list
function addList(element, clearInput = true) {
@@ -475,18 +458,43 @@ function initListInteractionOptions(element) {
// Perform action based on click count
if (clickCounter === 1) {
// Single-click action
- showModalFieldInput(
- ` ${getString(
- "Gen_Update_Value"
- )}`,
- getString("settings_update_item_warning"),
- getString("Gen_Cancel"),
- getString("Gen_Update"),
- $option.html(),
- function () {
- updateOptionItem($option, $(`#modal-field-input-field`).val());
- }
- );
+
+ const $parent = $option.parent();
+ const transformers = $parent.attr("my-transformers");
+
+ if (transformers && transformers === "name|base64") {
+ // Parent has my-transformers="name|base64"
+ const toId = $parent.attr("id");
+ const curValue = $option.val();
+ const parsed = JSON.parse(atob($parent.data("elementoptionsbase64")));
+ const popupFormJson = parsed.find(obj => "popupForm" in obj)?.popupForm ?? null;
+
+ showModalPopupForm(
+ ` ${getString(
+ "Gen_Update_Value"
+ )}`, // title
+ getString("settings_update_item_warning"), // message
+ getString("Gen_Cancel"), // btnCancel
+ getString("Gen_Update"), // btnOK
+ curValue, // curValue
+ popupFormJson, // popupform
+ toId, // parentSettingKey
+ this // triggeredBy
+ );
+ } else {
+ // Fallback to normal field input
+ showModalFieldInput(
+ ` ${getString("Gen_Update_Value")}`,
+ getString("settings_update_item_warning"),
+ getString("Gen_Cancel"),
+ getString("Gen_Update"),
+ $option.html(),
+ function () {
+ updateOptionItem($option, $(`#modal-field-input-field`).val());
+ }
+ );
+ }
+
} else if (clickCounter === 2) {
// Double-click action
removeOptionItem($option);
@@ -718,7 +726,7 @@ function applyTransformers(val, transformers) {
}
// ------------------------------------------------------------
-// Function to reverse transformers applied to a value
+// Function to reverse transformers applied to a value - returns the LABEL
function reverseTransformers(val, transformers) {
transformers.reverse().forEach((transformer) => {
switch (transformer) {
@@ -733,10 +741,10 @@ function reverseTransformers(val, transformers) {
}
break;
case "name|base64":
- // // Implement base64 decoding logic
- // if (isBase64(val)) {
- // val = atob(val);
- // }
+ // Implement base64 decoding logic
+ if (isBase64(val)) {
+ val = JSON.parse(atob(val))[0][3];
+ }
val = val; // probably TODO ⚠
break;
case "getString":
@@ -1089,7 +1097,6 @@ function collectSetting(prefix, setCodeName, setType, settingsArray) {
function generateFormHtml(settingsData, set, overrideValue, overrideOptions, originalSetKey) {
let inputHtml = '';
-
isEmpty(overrideValue) ? inVal = set['setValue'] : inVal = overrideValue;
const setKey = set['setKey'];
const setType = set['setType'];
@@ -1104,7 +1111,7 @@ function generateFormHtml(settingsData, set, overrideValue, overrideOptions, ori
// }
// Parse the setType JSON string
- console.log(processQuotes(setType));
+ // console.log(processQuotes(setType));
const setTypeObject = JSON.parse(processQuotes(setType))
const dataType = setTypeObject.dataType;
@@ -1166,6 +1173,7 @@ function generateFormHtml(settingsData, set, overrideValue, overrideOptions, ori
my-customparams="${customParams}"
my-customid="${customId}"
my-originalSetKey="${originalSetKey}"
+ data-elementoptionsbase64="${elementOptionsBase64}"
${multi}
${readOnly ? "disabled" : ""}>
diff --git a/front/plugins/unifi_api_import/README.md b/front/plugins/unifi_api_import/README.md
index 900fae41..0fd536b6 100755
--- a/front/plugins/unifi_api_import/README.md
+++ b/front/plugins/unifi_api_import/README.md
@@ -7,7 +7,7 @@ Unifi import plugin using the Site Manager API.
### Quick setup guide
-Navigate to your UniFi Site Manager _⚙️ Settings -> Control Plane -> Integrations_.
+Navigate to your UniFi Site Manager _Settings -> Control Plane -> Integrations_.
- `api_key` : You can generate your API key under the _Your API Keys_ section.
- `base_url` : You can find your base url in the _API Request Format_ section, e.g. `https://192.168.100.1/proxy/network/integration/`
diff --git a/front/plugins/unifi_api_import/config.json b/front/plugins/unifi_api_import/config.json
index 23bc8ff4..bd3ef1f7 100755
--- a/front/plugins/unifi_api_import/config.json
+++ b/front/plugins/unifi_api_import/config.json
@@ -208,9 +208,7 @@
"elementType": "button",
"elementOptions": [
{
- "sourceSuffixes": [
- "_in"
- ]
+ "sourceSuffixes": []
},
{
"separator": ""
@@ -223,6 +221,22 @@
},
{
"getStringKey": "Gen_Add"
+ }
+ ],
+ "transformers": []
+ },
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ {
+ "multiple": "true"
+ },
+ {
+ "readonly": "true"
+ },
+ {
+ "editable": "true"
},
{
"popupForm": [
@@ -237,14 +251,8 @@
{
"placeholder": "Enter value"
},
- {
- "suffix": "_in"
- },
{
"cssClasses": "col-sm-10"
- },
- {
- "prefillValue": "null"
}
],
"transformers": []
@@ -281,14 +289,8 @@
{
"placeholder": "https://host_ip/proxy/network/integration/"
},
- {
- "suffix": "_in"
- },
{
"cssClasses": "col-sm-10"
- },
- {
- "prefillValue": "null"
}
],
"transformers": []
@@ -315,7 +317,7 @@
]
},
{
- "function": "version",
+ "function": "api_version",
"type": {
"dataType": "string",
"elements": [
@@ -325,14 +327,8 @@
{
"placeholder": "v1"
},
- {
- "suffix": "_in"
- },
{
"cssClasses": "col-sm-10"
- },
- {
- "prefillValue": "null"
}
],
"transformers": []
@@ -369,14 +365,8 @@
{
"placeholder": "Enter value"
},
- {
- "suffix": "_in"
- },
{
"cssClasses": "col-sm-10"
- },
- {
- "prefillValue": "null"
}
],
"transformers": []
@@ -403,7 +393,7 @@
]
},
{
- "function": "hide.site.verify_ssl",
+ "function": "verify_ssl",
"type": {
"dataType": "boolean",
"elements": [
@@ -441,22 +431,6 @@
"transformers": []
}
],
- "transformers": []
- },
- {
- "elementType": "select",
- "elementHasInputValue": 1,
- "elementOptions": [
- {
- "multiple": "true"
- },
- {
- "readonly": "true"
- },
- {
- "editable": "true"
- }
- ],
"transformers": [
"name|base64"
]
@@ -520,7 +494,7 @@
"description": [
{
"language_code": "en_us",
- "string": "UniFi sites"
+ "string": "UniFi site configurations. Use a unique name for each site. You can find necessary details to configure this in your controller under Settings -> Control Plane -> Integrations."
}
]
}