diff --git a/front/deviceDetails.php b/front/deviceDetails.php
index 03c44d92..2847d15f 100755
--- a/front/deviceDetails.php
+++ b/front/deviceDetails.php
@@ -1149,7 +1149,7 @@ function initializeCalendar () {
} else {
setTimeout(() => {
updateIconPreview('#txtIcon')
- }, 100);
+ }, 500);
hideSpinner()
}
diff --git a/front/devices.php b/front/devices.php
index f5e8001a..092a845b 100755
--- a/front/devices.php
+++ b/front/devices.php
@@ -143,9 +143,23 @@
var tableOrder = [[3,'desc'], [0,'asc']];
var tableColumnHide = [];
+ var tableColumnOrder = [];
+ var tableColumnVisible = [];
- //initialize the table headers in the correct order
- var headersDefaultOrder = [
+
+
+
+ // Read parameters & Initialize components
+ callAfterAppInitialized(main)
+ showSpinner();
+
+
+
+// -----------------------------------------------------------------------------
+function main () {
+
+ //initialize the table headers in the correct order
+ var headersDefaultOrder = [
getString('Device_TableHead_Name'),
getString('Device_TableHead_Owner'),
getString('Device_TableHead_Type'),
@@ -173,16 +187,8 @@
// generate default order lists of given length
var columnsStr = JSON.stringify(Array.from({ length: headersDefaultOrder.length }, (_, i) => i));
- var tableColumnOrder = Array.from({ length: headersDefaultOrder.length }, (_, i) => i);
- var tableColumnVisible = tableColumnOrder;
-
- // Read parameters & Initialize components
- showSpinner();
- main();
-
-
-// -----------------------------------------------------------------------------
-function main () {
+ tableColumnOrder = Array.from({ length: headersDefaultOrder.length }, (_, i) => i);
+ tableColumnVisible = tableColumnOrder;
handleLoadingDialog()
diff --git a/front/js/common.js b/front/js/common.js
index d659ff71..20b5322b 100755
--- a/front/js/common.js
+++ b/front/js/common.js
@@ -10,9 +10,10 @@
// -----------------------------------------------------------------------------
var timerRefreshData = ''
-var emptyArr = ['undefined', "", undefined, null, 'null'];
-var UI_LANG = "English";
-var settingsJSON = {}
+var emptyArr = ['undefined', "", undefined, null, 'null'];
+var UI_LANG = "English";
+const allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "zh_cn"]; // needs to be same as in lang.php
+var settingsJSON = {}
// -----------------------------------------------------------------------------
@@ -207,98 +208,123 @@ function getSetting (key) {
// -----------------------------------------------------------------------------
// Get language string
// -----------------------------------------------------------------------------
-function cacheStrings()
-{
+function cacheStrings() {
return new Promise((resolve, reject) => {
- if(!getCache('completedCalls').includes('cacheStrings'))
- {
- // handle core strings and translations
- var allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "zh_cn"]; // needs to be same as in lang.php
-
- allLanguages.forEach(function (language_code) {
- $.get(`php/templates/language/${language_code}.json?nocache=${Date.now()}`, function (res) {
- // Iterate over each language
- Object.entries(res).forEach(([key, value]) => {
- // Store translations for each key-value pair
- setCache(`pia_lang_${key}_${language_code}`, value)
- });
-
- // handle strings and translations from plugins
- $.get(`api/table_plugins_language_strings.json?nocache=${Date.now()}`, function(res) {
-
- data = res["data"];
-
- data.forEach((langString) => {
- setCache(`pia_lang_${langString.String_Key}_${langString.Language_Code}`, langString.String_Value)
- });
- }).then(() => handleSuccess('cacheStrings', resolve())).catch(() => handleFailure('cacheStrings', reject("cacheStrings already completed"))); // handle AJAX synchronization
+
+ // Create a promise for each language
+ const languagePromises = allLanguages.map((language_code) => {
+ return new Promise((resolveLang, rejectLang) => {
+ // Fetch core strings and translations
+ $.get(`php/templates/language/${language_code}.json?nocache=${Date.now()}`)
+ .done((res) => {
+ // Iterate over each key-value pair and store the translations
+ Object.entries(res).forEach(([key, value]) => {
+ setCache(`pia_lang_${key}_${language_code}`, value);
+ });
+
+ // Fetch strings and translations from plugins
+ $.get(`api/table_plugins_language_strings.json?nocache=${Date.now()}`)
+ .done((pluginRes) => {
+ const data = pluginRes["data"];
+
+ // Store plugin translations
+ data.forEach((langString) => {
+ setCache(`pia_lang_${langString.String_Key}_${langString.Language_Code}`, langString.String_Value);
+ });
+
+ // Handle successful completion of language processing
+ handleSuccess(`cacheStrings[${language_code}]`, resolveLang);
+ })
+ .fail((pluginError) => {
+ // Handle failure in plugin strings fetching
+ rejectLang(pluginError);
+ });
+ })
+ .fail((error) => {
+ // Handle failure in core strings fetching
+ rejectLang(error);
+ });
});
});
- }
+
+ // Wait for all language promises to complete
+ Promise.all(languagePromises)
+ .then(() => {
+ // All languages processed successfully
+ resolve();
+ })
+ .catch((error) => {
+ // Handle failure in any of the language processing
+ handleFailure('cacheStrings', reject);
+ });
+
});
}
+// -----------------------------------------------------------------------------
// Get translated language string
-function getString (key) {
+function getString(key) {
- // handle initial load to make sure everything is set-up and cached
- handleFirstLoad(getString)
-
- UI_LANG = getSetting("UI_LANG");
+ function fetchString(key) {
+ UI_LANG = getSetting("UI_LANG");
- lang_code = 'en_us';
+ let lang_code = 'en_us';
- switch(UI_LANG)
- {
- case 'English':
- lang_code = 'en_us';
- break;
- case 'Spanish':
- lang_code = 'es_es';
- break;
- case 'German':
- lang_code = 'de_de';
- break;
- case 'French':
- lang_code = 'fr_fr';
- break;
- case 'Norwegian':
- lang_code = 'nb_no';
- break;
- case 'Polish (pl_pl)':
- lang_code = 'pl_pl';
- break;
- case 'Portuguese (pt_br)':
- lang_code = 'pt_br';
- break;
- case 'Turkish (tr_tr)':
- lang_code = 'tr_tr';
- break;
- case 'Italian (it_it)':
- lang_code = 'it_it';
- break;
- case 'Russian':
- lang_code = 'ru_ru';
- break;
- case 'Chinese (zh_cn)':
- lang_code = 'zh_cn';
- break;
- }
- result = getCache(`pia_lang_${key}_${lang_code}`, true);
+ switch (UI_LANG) {
+ case 'English':
+ lang_code = 'en_us';
+ break;
+ case 'Spanish':
+ lang_code = 'es_es';
+ break;
+ case 'German':
+ lang_code = 'de_de';
+ break;
+ case 'French':
+ lang_code = 'fr_fr';
+ break;
+ case 'Norwegian':
+ lang_code = 'nb_no';
+ break;
+ case 'Polish (pl_pl)':
+ lang_code = 'pl_pl';
+ break;
+ case 'Portuguese (pt_br)':
+ lang_code = 'pt_br';
+ break;
+ case 'Turkish (tr_tr)':
+ lang_code = 'tr_tr';
+ break;
+ case 'Italian (it_it)':
+ lang_code = 'it_it';
+ break;
+ case 'Russian':
+ lang_code = 'ru_ru';
+ break;
+ case 'Chinese (zh_cn)':
+ lang_code = 'zh_cn';
+ break;
+ }
+ let result = getCache(`pia_lang_${key}_${lang_code}`, true);
- if(isEmpty(result))
- {
- result = getCache(`pia_lang_${key}_en_us`, true);
+ if (isEmpty(result)) {
+ result = getCache(`pia_lang_${key}_en_us`, true);
+ }
+
+ return result;
}
- return result;
+ if (isAppInitialized()) {
+ return fetchString(key);
+ } else {
+ callAfterAppInitialized(() => fetchString(key));
+ }
}
-
// -----------------------------------------------------------------------------
// String utilities
// -----------------------------------------------------------------------------
@@ -334,6 +360,15 @@ function isValidBase64(str) {
}
+function isValidJSON(jsonString) {
+ try {
+ JSON.parse(jsonString);
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
// -----------------------------------------------------------------------------
// General utilities
// -----------------------------------------------------------------------------
@@ -835,7 +870,7 @@ function getDeviceDataByMac(macAddress, dbColumn) {
}
// -----------------------------------------------------------------------------
-// Cache teh devices as one JSON
+// Cache the devices as one JSON
function cacheDevices()
{
@@ -918,6 +953,8 @@ function showSpinner(stringKey='Loading')
text = getString(stringKey)
}
+ text = isEmpty(text) ? "Loading" : text;
+
if($("#loadingSpinner").length)
{
$("#loadingSpinner").show();
@@ -1102,6 +1139,8 @@ function arraysContainSameValues(arr1, arr2) {
const sessionStorageKey = "myScriptExecuted_common_js";
var completedCalls = []
var completedCalls_final = ['cacheSettings', 'cacheStrings', 'cacheDevices'];
+var completedCallsCount = 0;
+var completedCallsCount_final = allLanguages.length + 2; // number of language files + cacheDevices + cacheSettings
// -----------------------------------------------------------------------------
// Clearing all the caches
@@ -1139,10 +1178,24 @@ async function handleFirstLoad(callback) {
}
}
+// -----------------------------------------------------------------------------
+// Execute callback once app initialized
+function callAfterAppInitialized(callback) {
+ if (!isAppInitialized()) {
+ setTimeout(() => {
+ callAfterAppInitialized(callback)
+ }, 500);
+ } else
+ {
+ callback();
+ }
+}
+
// -----------------------------------------------------------------------------
// Check if the code has been executed before by checking sessionStorage
function isAppInitialized() {
- return arraysContainSameValues(getCache("completedCalls").split(',').filter(Boolean), completedCalls_final);
+ // return arraysContainSameValues(getCache("completedCalls").split(',').filter(Boolean), completedCalls_final);
+ return (parseInt(getCache("completedCallsCount")) == completedCallsCount_final);
}
// Define a function that will execute the code only once
@@ -1151,9 +1204,10 @@ async function executeOnce() {
if (!isAppInitialized()) {
try {
- await cacheStrings();
- await cacheSettings();
await cacheDevices();
+ await cacheSettings();
+ await cacheStrings();
+
console.log("✅ All AJAX callbacks have completed");
onAllCallsComplete();
} catch (error) {
@@ -1166,8 +1220,20 @@ async function executeOnce() {
// Function to handle successful completion of an AJAX call
const handleSuccess = (callName) => {
console.log(`AJAX call successful: ${callName}`);
- completedCalls.push(callName);
- setCache('completedCalls', mergeUniqueArrays(getCache('completedCalls').split(','), [callName]));
+ // completedCalls.push(callName);
+ // setCache('completedCalls', mergeUniqueArrays(getCache('completedCalls').split(','), [callName]));
+
+ val = getCache('completedCallsCount');
+
+ if(val == "")
+ {
+ val = 0;
+ } else
+ {
+ val = parseInt(val)
+ }
+
+ setCache('completedCallsCount', val + 1)
};
// -----------------------------------------------------------------------------
@@ -1190,6 +1256,10 @@ const onAllCallsComplete = () => {
sessionStorage.setItem(sessionStorageKey + '_time', millisecondsNow);
console.log('✔ Cache initialized');
+ // setTimeout(() => {
+ // location.reload()
+ // }, 10);
+
} else {
// If not all strings are initialized, retry initialization
console.log('❌ Not all strings are initialized. Retrying...');
@@ -1199,14 +1269,13 @@ const onAllCallsComplete = () => {
// Call any other initialization functions here if needed
- // No need for location.reload() here
};
// Function to check if all necessary strings are initialized
const areAllStringsInitialized = () => {
// Implement logic to check if all necessary strings are initialized
// Return true if all strings are initialized, false otherwise
- return getString('UI_LANG') != ""
+ return getString('UI_LANG_name') != ""
};
// Call the function to execute the code
diff --git a/front/js/db_methods.js b/front/js/db_methods.js
index 363f273f..c0373a99 100755
--- a/front/js/db_methods.js
+++ b/front/js/db_methods.js
@@ -89,7 +89,7 @@ function checkDbLock() {
type: "GET",
success: function (response) {
- console.log(response);
+ // console.log(response);
if (response == 0) {
// console.log('Database is not locked');
$(".header-status-locked-db").hide();
diff --git a/front/js/settings_utils.js b/front/js/settings_utils.js
index a810e41f..52ae1b81 100755
--- a/front/js/settings_utils.js
+++ b/front/js/settings_utils.js
@@ -259,7 +259,8 @@ function addList(element, clearInput = true) {
.attr("value", input)
.text(input);
- const el = $(`#${toId}`).append(newOption);
+ // add new option
+ $(`#${toId}`).append(newOption);
// clear input
if (clearInput) {
@@ -269,6 +270,7 @@ function addList(element, clearInput = true) {
// Initialize interaction options only for the newly added option
initListInteractionOptions(newOption);
+ // flag something changes to prevent navigating from page
settingsChanged();
}
@@ -279,31 +281,6 @@ function removeFromList(element) {
.find("option:last")
.remove();
}
-// ---------------------------------------------------------
-function addInterface() {
- ipMask = $("#ipMask").val();
- ipInterface = $("#ipInterface").val();
-
- full = ipMask + " --interface=" + ipInterface;
-
- console.log(full);
-
- if (ipMask == "" || ipInterface == "") {
- showModalOk(
- "Validation error",
- "Specify both, the network mask and the interface"
- );
- } else {
- $("#SCAN_SUBNETS").append(
- $("").attr("value", full).text(full)
- );
-
- $("#ipMask").val("");
- $("#ipInterface").val("");
-
- settingsChanged();
- }
-}
// -------------------------------------------------------------------
// Function to remove an item from the select element
@@ -555,7 +532,7 @@ function generateOptionsOrSetOptions(
transformers = [] // Transformers to be applied to the values
) {
- console.log(codeName);
+ // console.log(codeName);
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
options = arrayToObject(createArray(getSettingOptions(codeName)))
diff --git a/front/js/ui_components.js b/front/js/ui_components.js
index 9158b185..40a5f0fe 100755
--- a/front/js/ui_components.js
+++ b/front/js/ui_components.js
@@ -11,16 +11,7 @@
// -----------------------------------------------------------------------------
// Initialize device selectors / pickers fields
// -----------------------------------------------------------------------------
-function initDeviceSelectors() {
-
- // console.log(devicesList)
- // Retrieve device list from session variable
- var devicesListAll_JSON = getCache('devicesListAll_JSON');
-
- var devicesList = JSON.parse(devicesListAll_JSON);
-
- // console.log(devicesList);
-
+function initDeviceSelectors(devicesListAll_JSON) {
// Check if both device list exists
if (devicesListAll_JSON) {
@@ -78,52 +69,6 @@ function initDeviceSelectors() {
-// // -----------------------------------------------------------------------------
-// // (ASYNC) Initiate dropdown
-// function generateSetOptions(settingKey, // Identifier for the setting
-// valuesArray, // Array of values to be pre-selected in the dropdown
-// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
-// callbackToGenerateEntries, // Callback function to generate entries based on options
-// targetField, // Target field or element where selected value should be applied or updated
-// nameTransformer) // callback to transform the name (e.g. base64)
-// {
-
-// var optionsHtml = ""
-
-// // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
-// optionsArray = createArray(getSettingOptions(settingKey))
-
-
-// // check if the result is a SQL query
-// if(optionsArray.length > 0 && isSQLQuery(optionsArray[0]))
-// {
-
-// if (settingKey == "NEWDEV_dev_Network_Node_MAC_ADDR") {
-// console.log("isSQLQuery in generateSetOptions");
-
-// }
-// readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer);
-
-// } else // this should be already an array, e.g. from a setting or pre-defined
-// {
-// optionsArray.forEach(option => {
-// let selected = valuesArray.includes(option) ? 'selected' : '';
-// optionsHtml += ``;
-// });
-
-// // Replace the specified placeholder div with the resulting HTML
-// setTimeout(() => {
-
-// $("#" + targetLocation).replaceWith(optionsHtml);
-
-// }, 50);
-// }
-
-
-
-// }
-
-
// -----------------------------------------------------------------------------
// Hide elements on the page based on the supplied setting
function hideUIelements(settingKey) {
@@ -290,42 +235,57 @@ function getCellValue(row, index) {
// initialize
// -----------------------------------------------------------------------------
+function initSelect2() {
-setTimeout(() => {
+ // Retrieve device list from session variable
+ var devicesListAll_JSON = getCache('devicesListAll_JSON');
- initDeviceSelectors();
+ // check if cache ready
+ if(isValidJSON(devicesListAll_JSON))
+ {
+ // prepare HTML DOM before initializing the frotend
+ initDeviceSelectors(devicesListAll_JSON)
-
- // --------------------------------------------------------
- //Initialize Select2 Elements and make them sortable
-
- $(function () {
- // Iterate over each Select2 dropdown
- $('.select2').each(function() {
- var selectEl = $(this).select2();
-
- // Apply sortable functionality to the dropdown's dropdown-container
- selectEl.next().children().children().children().sortable({
- containment: 'parent',
- update: function () {
- var sortedValues = $(this).children().map(function() {
- return $(this).attr('title');
- }).get();
-
- var sortedOptions = selectEl.find('option').sort(function(a, b) {
- return sortedValues.indexOf($(a).text()) - sortedValues.indexOf($(b).text());
- });
-
- // Replace all options in selectEl
- selectEl.empty().append(sortedOptions);
-
- // Trigger change event on Select2
- selectEl.trigger('change');
- }
- });
+
+ // --------------------------------------------------------
+ //Initialize Select2 Elements and make them sortable
+ $(function () {
+ // Iterate over each Select2 dropdown
+ $('.select2').each(function() {
+ var selectEl = $(this).select2();
+
+ // Apply sortable functionality to the dropdown's dropdown-container
+ selectEl.next().children().children().children().sortable({
+ containment: 'parent',
+ update: function () {
+ var sortedValues = $(this).children().map(function() {
+ return $(this).attr('title');
+ }).get();
+
+ var sortedOptions = selectEl.find('option').sort(function(a, b) {
+ return sortedValues.indexOf($(a).text()) - sortedValues.indexOf($(b).text());
+ });
+
+ // Replace all options in selectEl
+ selectEl.empty().append(sortedOptions);
+
+ // Trigger change event on Select2
+ selectEl.trigger('change');
+ }
+ });
+ });
});
- });
-
+ } else // cache not ready try later
+ {
+ setTimeout(() => {
+ initSelect2()
+ }, 1000);
+ }
+}
+
+// try to initialize select2
+setTimeout(() => {
+ initSelect2()
}, 500);
diff --git a/front/multiEditCore.php b/front/multiEditCore.php
index c8f6bb38..987327ab 100755
--- a/front/multiEditCore.php
+++ b/front/multiEditCore.php
@@ -101,10 +101,19 @@
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
const setTypeObject = JSON.parse(columns[j].Type.replace(/'/g, '"'));
- // console.log(setTypeObject);
- const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]
+ // console.log(setTypeObject); 🔽
+ // const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]
- const { elementType, elementOptions = [], transformers = [] } = lastElementObj;
+ // get the element with the input value(s)
+ let elementsWithInputValue = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
+
+ // if none found, take last
+ if(elementsWithInputValue.length == 0)
+ {
+ elementsWithInputValue = setTypeObject.elements[setTypeObject.elements.length - 1]
+ }
+
+ const { elementType, elementOptions = [], transformers = [] } = elementsWithInputValue;
const {
inputType,
readOnly,
@@ -123,8 +132,8 @@
// console.log(setTypeObject);
// console.log(inputType);
- // render based on element type
- if (lastElementObj.elementType === 'select') {
+ // render based on element type
+ if (elementsWithInputValue.elementType === 'select') {
targetLocation = columns[j].Code_Name + "_generateSetOptions"
@@ -154,7 +163,7 @@
}
- } else if (lastElementObj.elementType === 'input'){
+ } else if (elementsWithInputValue.elementType === 'input'){
// Add classes specifically for checkboxes
inputType === 'checkbox' ? inputClass = 'checkbox' : inputClass = 'form-control';
diff --git a/front/plugins/__template/config.json b/front/plugins/__template/config.json
index dafc1986..639bb89f 100755
--- a/front/plugins/__template/config.json
+++ b/front/plugins/__template/config.json
@@ -173,6 +173,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -194,15 +204,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
diff --git a/front/plugins/dhcp_leases/config.json b/front/plugins/dhcp_leases/config.json
index 4900929b..996d7e92 100755
--- a/front/plugins/dhcp_leases/config.json
+++ b/front/plugins/dhcp_leases/config.json
@@ -525,6 +525,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -546,15 +556,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
diff --git a/front/plugins/newdev_template/config.json b/front/plugins/newdev_template/config.json
index 1d2b0357..c61653e3 100755
--- a/front/plugins/newdev_template/config.json
+++ b/front/plugins/newdev_template/config.json
@@ -52,6 +52,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -73,15 +83,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
@@ -127,6 +128,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -148,15 +159,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
@@ -194,14 +196,24 @@
{
"elementType": "button",
"elementOptions": [
- { "sourceSuffixes": [] },
+ { "sourceSuffixes": ["_in"] },
{ "separator": "" },
- { "cssClasses": "col-sm-3" },
- { "onClick": "removeAllOptions(this)" },
- { "getStringKey": "Gen_Remove_All" }
+ { "cssClasses": "col-sm-2" },
+ { "onClick": "addList(this, false)" },
+ { "getStringKey": "Gen_Add" }
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": ["base64"]
+ },
{
"elementType": "button",
"elementOptions": [
@@ -216,22 +228,13 @@
{
"elementType": "button",
"elementOptions": [
- { "sourceSuffixes": ["_in"] },
+ { "sourceSuffixes": [] },
{ "separator": "" },
- { "cssClasses": "col-sm-2" },
- { "onClick": "addList(this, false)" },
- { "getStringKey": "Gen_Add" }
+ { "cssClasses": "col-sm-3" },
+ { "onClick": "removeAllOptions(this)" },
+ { "getStringKey": "Gen_Remove_All" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": ["base64"]
}
]
},
diff --git a/front/plugins/omada_sdn_imp/config.json b/front/plugins/omada_sdn_imp/config.json
index 3aff59b6..31fc14d0 100755
--- a/front/plugins/omada_sdn_imp/config.json
+++ b/front/plugins/omada_sdn_imp/config.json
@@ -155,6 +155,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -176,15 +186,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
diff --git a/front/plugins/snmp_discovery/config.json b/front/plugins/snmp_discovery/config.json
index 67f72466..7c58372f 100755
--- a/front/plugins/snmp_discovery/config.json
+++ b/front/plugins/snmp_discovery/config.json
@@ -434,6 +434,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -455,15 +465,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
diff --git a/front/plugins/undiscoverables/config.json b/front/plugins/undiscoverables/config.json
index 106e252a..a9be9fef 100755
--- a/front/plugins/undiscoverables/config.json
+++ b/front/plugins/undiscoverables/config.json
@@ -301,6 +301,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -322,15 +332,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
diff --git a/front/plugins/unifi_import/config.json b/front/plugins/unifi_import/config.json
index 85d7763e..2336d062 100755
--- a/front/plugins/unifi_import/config.json
+++ b/front/plugins/unifi_import/config.json
@@ -271,6 +271,7 @@
},
{
"column": "Watched_Value3",
+ "mapped_to_column": "cur_Type",
"css_classes": "col-sm-2",
"default_value": "",
"localized": ["name"],
@@ -776,6 +777,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -797,15 +808,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
}
diff --git a/front/plugins/website_monitor/config.json b/front/plugins/website_monitor/config.json
index f151bc10..23e7ea9f 100755
--- a/front/plugins/website_monitor/config.json
+++ b/front/plugins/website_monitor/config.json
@@ -624,6 +624,16 @@
],
"transformers": []
},
+ {
+ "elementType": "select",
+ "elementHasInputValue": 1,
+ "elementOptions": [
+ { "multiple": "true" },
+ { "readonly": "true" },
+ { "editable": "true" }
+ ],
+ "transformers": []
+ },
{
"elementType": "button",
"elementOptions": [
@@ -645,15 +655,6 @@
{ "getStringKey": "Gen_Remove_Last" }
],
"transformers": []
- },
- {
- "elementType": "select",
- "elementOptions": [
- { "multiple": "true" },
- { "readonly": "true" },
- { "editable": "true" }
- ],
- "transformers": []
}
]
},
diff --git a/front/settings.php b/front/settings.php
index 7fbae9e4..12fbe9b2 100755
--- a/front/settings.php
+++ b/front/settings.php
@@ -219,7 +219,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
try {
const isMetadata = codeName.includes('__metadata');
- // is this isn't a metadata entry, get corresponding metadata object from the dummy setting
+ // if this isn't a metadata entry, get corresponding metadata object from the dummy setting
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${codeName}__metadata`));
} catch (error) {
@@ -459,6 +459,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
}
// INPUT
+
+ console.log(codeName);
// Parse the setType JSON string into an object
let inputHtml = '';
@@ -614,8 +616,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
clearCache()
}, 1500);
- } else
- {
+ } else {
var settingsArray = [];
// collect values for each of the different input form controls
@@ -628,12 +629,18 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
setType = set["Type"]
setCodeName = set["Code_Name"]
+ console.log(prefix);
+
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
// console.log(setTypeObject);
const dataType = setTypeObject.dataType;
- const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1];
- const { elementType, elementOptions = [], transformers = [] } = lastElementObj;
+ // const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]; //🔽
+
+ // get the element with the input value(s)
+ const elementsWithInputValue = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
+
+ const { elementType, elementOptions = [], transformers = [] } = elementsWithInputValue;
const {
inputType,
readOnly,
@@ -714,13 +721,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
success: function(data, textStatus) {
if(data == "OK")
- {
- showMessage (getString("settings_saved"), 5000, "modal_grey");
+ {
+ // showMessage (getString("settings_saved"), 5000, "modal_grey");
// Remove navigation prompt "Are you sure you want to leave..."
window.onbeforeunload = null;
// Reloads the current page
- setTimeout("clearCache()", 5000);
+ // setTimeout("clearCache()", 5000);
+
+ clearCache()
} else{
// something went wrong
// write_notification(data, 'interrupt')
@@ -746,7 +755,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX