From 1c4e6c7e389bcbd1208592cdc1292071e7edb892 Mon Sep 17 00:00:00 2001 From: jokob-sk Date: Mon, 11 Aug 2025 15:00:22 +1000 Subject: [PATCH] UNIFIAPI v0.3 FE setings done --- front/js/modal.js | 71 +++++++++----- front/js/settings_utils.js | 104 +++++++++++---------- front/plugins/unifi_api_import/README.md | 2 +- front/plugins/unifi_api_import/config.json | 66 ++++--------- 4 files changed, 126 insertions(+), 117 deletions(-) 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." } ] }