🔌 Omada work #708

This commit is contained in:
jokob-sk
2024-07-05 23:53:55 +10:00
parent f03f3f33b1
commit eff98257d6
11 changed files with 110 additions and 69 deletions

View File

@@ -245,18 +245,28 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// --------------------------------------------------------- // ---------------------------------------------------------
function addList(element) function addList(element, clearInput = true)
{ {
const fromId = $(element).attr('my-input-from'); const fromId = $(element).attr('my-input-from');
const toId = $(element).attr('my-input-to'); const toId = $(element).attr('my-input-to');
input = $(`#${fromId}`).val(); input = $(`#${fromId}`).val();
console.log(input);
console.log(toId);
console.log($(`#${toId}`));
$(`#${toId}`).append($("<option ></option>").attr("value", input).text(input)); $(`#${toId}`).append($("<option ></option>").attr("value", input).text(input));
// clear input // clear input
$(`#${fromId}`).val(""); if (clearInput)
{
$(`#${fromId}`).val("");
}
settingsChanged(); settingsChanged();
} }
// --------------------------------------------------------- // ---------------------------------------------------------
@@ -340,6 +350,8 @@ function initListInteractionOptions(selectorId) {
// Perform action based on click count // Perform action based on click count
if (clickCounter === 1) { if (clickCounter === 1) {
// Single-click action // Single-click action
// btoa(iconHtml.replace(/"/g, "'") <-- encode
// atob() <--- decode
showModalFieldInput( showModalFieldInput(
`<i class="fa-regular fa-pen-to-square"></i> ${getString('Gen_Update_Value')}`, `<i class="fa-regular fa-pen-to-square"></i> ${getString('Gen_Update_Value')}`,
getString('settings_update_item_warning'), getString('settings_update_item_warning'),
@@ -480,7 +492,7 @@ function getParam(targetId, key, skipCache = false) {
// --------------------------------------------------------- // ---------------------------------------------------------
// generate a list of options for a input select // generate a list of options for a input select
function generateInputOptions(pluginsData, set, input, isMultiSelect = false) function generateOptions(pluginsData, set, input, isMultiSelect = false, isValueSource = true)
{ {
multi = isMultiSelect ? "multiple" : ""; multi = isMultiSelect ? "multiple" : "";
@@ -492,15 +504,19 @@ function getParam(targetId, key, skipCache = false) {
var targetLocation = set['Code_Name'] + "_initSettingDropdown"; var targetLocation = set['Code_Name'] + "_initSettingDropdown";
// execute AJAX callabck + SQL query resolution // execute AJAX callabck + SQL query resolution
initSettingDropdown(set['Code_Name'] , valuesArray, targetLocation, generateDropdownOptions) initSettingDropdown(set['Code_Name'] , valuesArray, targetLocation, generateDropdownOptions);
// generate different ID depending on if it's the source for the value to be saved or only used as an input
isValueSource ? id = set['Code_Name'] : id = set['Code_Name'] + '_input';
// main selection dropdown wrapper // main selection dropdown wrapper
input += ` input += `
<select onChange="settingsChanged()" <select onChange="settingsChanged()"
my-data-type="${set['Type']}" my-data-type="${set['Type']}"
class="form-control" class="form-control"
name="${set['Code_Name']}" name="${set['Code_Name']}"
id="${set['Code_Name']}" ${multi}> id="${id}"
${multi}>
<option id="${targetLocation}" temporary="temporary"></option> <option id="${targetLocation}" temporary="temporary"></option>

View File

@@ -390,7 +390,7 @@ $db->close();
</div> </div>
<div class="db_info_table_row"> <div class="db_info_table_row">
<div class="db_tools_table_cell_a" > <div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="askExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button> <button type="button" class="btn btn-default pa-btn bg-green dbtools-button" id="btnExportCSV" onclick="ExportCSV()"><?= lang('Maintenance_Tool_ExportCSV');?></button>
</div> </div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div> <div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_ExportCSV_text');?></div>
</div> </div>
@@ -640,11 +640,6 @@ function restartBackend() {
// ----------------------------------------------------------- // -----------------------------------------------------------
// Export CSV // Export CSV
function askExportCSV() {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_ExportCSV_noti');?>', '<?= lang('Maintenance_Tool_ExportCSV_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'ExportCSV');
}
function ExportCSV() function ExportCSV()
{ {
// Execute // Execute

View File

@@ -528,8 +528,10 @@
for(var i in list) for(var i in list)
{ {
//... of the current node //... of the current node
if(list[i].parentMac == node.mac && !hiddenMacs.includes(list[i].parentMac))
if(list[i].parentMac.toLowerCase() == node.mac.toLowerCase() && !hiddenMacs.includes(list[i].parentMac))
{ {
visibleNodesCount++ visibleNodesCount++
// and process them // and process them
@@ -570,7 +572,6 @@
function getHierarchy() function getHierarchy()
{ {
for(i in deviceListGlobal) for(i in deviceListGlobal)
{ {
if(deviceListGlobal[i].mac == 'Internet') if(deviceListGlobal[i].mac == 'Internet')
@@ -618,7 +619,7 @@
// Handle network node click - select correct tab in teh bottom table // Handle network node click - select correct tab in teh bottom table
function handleNodeClick(event) function handleNodeClick(event)
{ {
console.log(event.target.offsetParent.offsetParent) // console.log(event.target.offsetParent.offsetParent)
const targetTabMAC = $(event.target.offsetParent.offsetParent).attr("data-mytreemacmain"); const targetTabMAC = $(event.target.offsetParent.offsetParent).attr("data-mytreemacmain");
@@ -728,7 +729,7 @@
onNodeClick: (nodeData) => handleNodeClick(nodeData), onNodeClick: (nodeData) => handleNodeClick(nodeData),
relationnalField: "children", relationnalField: "children",
}); });
console.log(myHierarchy) console.log(myHierarchy)
myTree.refresh(myHierarchy); myTree.refresh(myHierarchy);

View File

@@ -353,7 +353,7 @@ function saveSettings()
} }
$txt .= $settingKey . "=" . $val . "\n"; $txt .= $settingKey . "=" . $val . "\n";
} elseif ($settingType == 'text.multiselect' || $settingType == 'subnets' || $settingType == 'list' || $settingType == 'list.select') { } elseif ($settingType == 'text.multiselect' || $settingType == 'subnets' || $settingType == 'list' || $settingType == 'list.select' || $settingType == 'list.base64') {
$temp = ''; $temp = '';
if(is_array($settingValue) == FALSE) if(is_array($settingValue) == FALSE)

View File

@@ -279,7 +279,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>" "string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> type </li></ul>"
}, },
{ {
"language_code": "de_de", "language_code": "de_de",
@@ -426,6 +426,22 @@
} }
] ]
}, },
{
"column": "Watched_Value4",
"mapped_to_column": "cur_Type",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Type"
}
]
},
{ {
"column": "Dummy", "column": "Dummy",
"mapped_to_column": "cur_ScanMethod", "mapped_to_column": "cur_ScanMethod",

View File

@@ -71,7 +71,7 @@ def main():
watched1 = f'Previous IP: {PREV_IP}', watched1 = f'Previous IP: {PREV_IP}',
watched2 = cmd_output.replace('\n',''), watched2 = cmd_output.replace('\n',''),
watched3 = retries_needed, watched3 = retries_needed,
watched4 = '', watched4 = 'Gateway',
extra = f'Previous IP: {PREV_IP}', extra = f'Previous IP: {PREV_IP}',
foreignKey = 'Internet') foreignKey = 'Internet')

View File

@@ -630,7 +630,7 @@
}, },
{ {
"function": "NAME_CLEANUP_REGEX", "function": "NAME_CLEANUP_REGEX",
"type": "list", "type": "list.base64",
"default_value": ["XC5fYWlycGxheQ==", "XC5fdGNw", "XC5sb2NhbGRvbWFpbg==", "XC5sb2NhbA==", "XC5fZXNwaG9tZWxpYg==", "XC5fZ29vZ2xlY2FzdA==", "XC5sYW4=", "XC5ob21l", "LVthLWZBLUYwLTldezMyfQ==", "Iy4q" ], "default_value": ["XC5fYWlycGxheQ==", "XC5fdGNw", "XC5sb2NhbGRvbWFpbg==", "XC5sb2NhbA==", "XC5fZXNwaG9tZWxpYg==", "XC5fZ29vZ2xlY2FzdA==", "XC5sYW4=", "XC5ob21l", "LVthLWZBLUYwLTldezMyfQ==", "Iy4q" ],
"options": [], "options": [],
"localized": ["name", "description"], "localized": ["name", "description"],

View File

@@ -434,7 +434,7 @@
}, },
{ {
"column": "Extra", "column": "Extra",
"mapped_to_column": "cur_NetworkSite", "mapped_to_column": "cur_Type",
"css_classes": "col-sm-2", "css_classes": "col-sm-2",
"show": false, "show": false,
"type": "label", "type": "label",

View File

@@ -65,7 +65,7 @@ def main():
mylog('verbose', [f'[{pluginName}] New entries: "{len(new_devices)}"']) mylog('verbose', [f'[{pluginName}] New entries: "{len(new_devices)}"'])
# log result # log result
plugin_objects.write_result_file() # plugin_objects.write_result_file()
return 0 return 0

View File

@@ -26,12 +26,9 @@ $settingsJson = json_decode($data);
// get settings from the DB // get settings from the DB
global $db; global $db;
global $settingKeyOfLists;
$result = $db->query("SELECT * FROM Settings"); $result = $db->query("SELECT * FROM Settings");
// array
$settingKeyOfLists = array();
$settings = array(); $settings = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
@@ -52,7 +49,6 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
?> ?>
<!-- Page ------------------------------------------------------------------ --> <!-- Page ------------------------------------------------------------------ -->
<!-- Page ------------------------------------------------------------------ -->
<script src="js/settings_utils.js?v=<?php include 'php/templates/version.php'; ?>"></script> <script src="js/settings_utils.js?v=<?php include 'php/templates/version.php'; ?>"></script>
@@ -253,7 +249,6 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
function initSettingsPage(settingsData, pluginsData){ function initSettingsPage(settingsData, pluginsData){
const settingPluginPrefixes = []; const settingPluginPrefixes = [];
const settingKeyOfLists = [];
const enabledDeviceScanners = getPluginsByType(pluginsData, "device_scanner", true); const enabledDeviceScanners = getPluginsByType(pluginsData, "device_scanner", true);
const enabledOthers = getPluginsByType(pluginsData, "other", true); const enabledOthers = getPluginsByType(pluginsData, "other", true);
@@ -470,11 +465,11 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// --- process text --- // --- process text ---
if(setType.includes(".select")) if(setType.includes(".select"))
{ {
inputHtml = generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = false) inputHtml = generateOptions(pluginsData, set, inputHtml, isMultiSelect = false)
} else if(setType.includes(".multiselect")) } else if(setType.includes(".multiselect"))
{ {
inputHtml = generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = true) inputHtml = generateOptions(pluginsData, set, inputHtml, isMultiSelect = true)
} else{ } else{
// if it's overridable set readonly accordingly // if it's overridable set readonly accordingly
@@ -507,7 +502,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
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(pluginsData, set, inputHtml) inputHtml = generateOptions(pluginsData, set, inputHtml)
} else if (setType === 'subnets') { } else if (setType === 'subnets') {
// --- process subnets --- // --- process subnets ---
@@ -543,18 +538,20 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
${getString("Gen_Remove_All")} ${getString("Gen_Remove_All")}
</button> </button>
</div>`; </div>`;
} else if (setType === 'list' || setType === 'list.select' || setType === 'list.readonly') { } else if (setType.startsWith('list')) {
// --- process list --- // --- process list ---
settingKeyOfLists.push(codeName);
inputHtml += ` inputHtml += `
<div class="row form-group"> <div class="row form-group">
<div class="col-xs-9">` <div class="col-xs-9">`
if(setType.includes(".select")) // not tested if(setType.includes(".select")) // not tested
{ {
inputHtml += generateInputOptions(pluginsData, set, inputHtml, isMultiSelect = false) inputHtml += generateOptions(pluginsData, set, inputHtml, isMultiSelect = false, isValueSource = false)
}
else if(setType.includes(".multiselect"))
{
inputHtml += generateOptions(pluginsData, set, inputHtml, isMultiSelect = true)
} }
else else
{ {
@@ -565,7 +562,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
inputHtml += `</div> inputHtml += `</div>
<div class="col-xs-3"> <div class="col-xs-3">
<button class="btn btn-primary" my-input-from="${codeName}_input" my-input-to="${codeName}" onclick="addList(this);initListInteractionOptions('${codeName}')">${getString("Gen_Add")}</button> <button class="btn btn-primary" my-input-from="${codeName}_input" my-input-to="${codeName}" onclick="addList(this, false);initListInteractionOptions('${codeName}')">${getString("Gen_Add")}</button>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -623,7 +620,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
$(`#${prefix} .panel-body`).append(setHtml); $(`#${prefix} .panel-body`).append(setHtml);
// init remove and edit listitem click gestures // init remove and edit listitem click gestures
if(['subnets', 'list' ].includes(setType)) if(['subnets'].includes(setType) || setType.startsWith('list'))
{ {
initListInteractionOptions(codeName) initListInteractionOptions(codeName)
} }
@@ -640,8 +637,6 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
} }
// display the name of the first person // display the name of the first person
// echo $settingsJson[0]->name; // echo $settingsJson[0]->name;
var settingsNumberDB = <?php echo count($settings)?>; var settingsNumberDB = <?php echo count($settings)?>;
@@ -671,52 +666,58 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
var settingsArray = []; var settingsArray = [];
// collect values for each of the different input form controls // collect values for each of the different input form controls
const noConversion = ['text', 'integer', 'string', 'password', 'readonly', 'text.select', 'list.select', 'integer.select', 'text.multiselect']; const noConversion = ['text', 'integer', 'string', 'password', 'readonly', 'text.select', 'integer.select', 'text.multiselect'];
// get settings to determine setting type to store values appropriately // get settings to determine setting type to store values appropriately
$.get('api/table_settings.json?nocache=' + Date.now(), function(res) { $.get('api/table_settings.json?nocache=' + Date.now(), function(res) {
// loop through the settings definitions from the json
settingsJSON = res; res["data"].forEach(set => {
prefix = set["Group"]
setType = set["Type"]
setCodeName = set["Code_Name"]
if (noConversion.includes(setType)) {
settingsArray.push([prefix, setCodeName, setType, $('#'+setCodeName).val()]);
} else if (setType === 'boolean' || setType === 'integer.checkbox') {
data = settingsJSON["data"]; const temp = $(`#${setCodeName}`).is(':checked') ? 1 : 0;
settingsArray.push([prefix, setCodeName, setType, temp]);
data.forEach(set => {
if (noConversion.includes(set['Type'])) {
settingsArray.push([set["Group"], set["Code_Name"], set["Type"], $('#'+set["Code_Name"]).val()]);
} else if (set['Type'] === 'boolean' || set['Type'] === 'integer.checkbox') {
const temp = $(`#${set["Code_Name"]}`).is(':checked') ? 1 : 0;
settingsArray.push([set["Group"], set["Code_Name"], set["Type"], temp]);
} else if (set['Type'] === 'list' || set['Type'] === 'subnets') { } else if (setType.startsWith('list') || setType === 'subnets') {
const temps = []; const temps = [];
$(`#${set["Code_Name"]} option`).each(function (i, selected) { $(`#${setCodeName} option`).each(function (i, selected) {
const vl = $(selected).val(); const vl = $(selected).val();
if (vl !== '') { if (vl !== '') {
temps.push(vl); temps.push(vl);
} }
}); });
settingsArray.push([set["Group"], set["Code_Name"], set["Type"], JSON.stringify(temps)]);
} else if (set['Type'] === 'json') { settingsArray.push([prefix, setCodeName, setType, JSON.stringify(temps)]);
const temps = $('#'+set["Code_Name"]).val(); } else if (setType === 'json') {
settingsArray.push([set["Group"], set["Code_Name"], set["Type"], temps]); const temps = $('#'+setCodeName).val();
} else if (set['Type'] === 'password.SHA256') { settingsArray.push([prefix, setCodeName, setType, temps]);
} else if (setType === 'password.SHA256') {
// save value as SHA256 if value isn't SHA256 already // save value as SHA256 if value isn't SHA256 already
var temps = $('#'+set["Code_Name"]).val(); var temps = $('#'+setCodeName).val();
if(temps != "" && !isSHA256(temps)) if(temps != "" && !isSHA256(temps))
{ {
temps = CryptoJS.SHA256(temps).toString(CryptoJS.enc.Hex); temps = CryptoJS.SHA256(temps).toString(CryptoJS.enc.Hex);
} }
settingsArray.push([set["Group"], set["Code_Name"], set["Type"], temps]); settingsArray.push([prefix, setCodeName, setType, temps]);
} }
}); });
// sanity check to make sure settings were loaded & collected correctly // sanity check to make sure settings were loaded & collected correctly
if(settingsCollectedCorrectly(settingsArray, settingsJSON_DB)) if(settingsCollectedCorrectly(settingsArray, settingsJSON_DB))
{ {
// console.log(settingsArray);
// trigger a save settings event in the backend // trigger a save settings event in the backend
$.ajax({ $.ajax({
method: "POST", method: "POST",

View File

@@ -314,7 +314,7 @@ def get_setting_value(key):
# Convert the setting value to the corresponding python type # Convert the setting value to the corresponding python type
def setting_value_to_python_type(set_type, set_value): def setting_value_to_python_type(set_type, set_value):
value = '' value = '----not processed----'
# Handle different types of settings # Handle different types of settings
if set_type in ['text', 'string', 'password', 'password.SHA256', 'readonly', 'text.select']: if set_type in ['text', 'string', 'password', 'password.SHA256', 'readonly', 'text.select']:
@@ -332,23 +332,35 @@ def setting_value_to_python_type(set_type, set_value):
elif set_type in ['integer.select', 'integer']: elif set_type in ['integer.select', 'integer']:
value = int(set_value) value = int(set_value)
# belwo covers 'text.multiselect', 'list', 'subnets', 'list.select', 'textarea.list', 'list' # belwo covers 'text.multiselect', 'list', 'subnets', 'list.select', 'list'
elif set_type in ['text.multiselect', 'list', 'subnets', 'list.select', 'textarea.list'] or 'list' in set_type: elif set_type in ['subnets' ] or 'list' in set_type:
# Handle string
mylog('debug', [f'[SETTINGS] Handling set_type: "{set_type}", set_value: "{set_value}"']) mylog('debug', [f'[SETTINGS] Handling set_type: "{set_type}", set_value: "{set_value}"'])
# Handle string
if isinstance(set_value, str): if isinstance(set_value, str):
value = json.loads(set_value.replace("'", "\"")) value = json.loads(set_value.replace("'", "\""))
# Assuming set_value is a list in this case
elif isinstance(set_value, list): # Assuming set_value is a list at this point
if isinstance(set_value, list):
if 'base64' in set_type:
tmp_value = []
for item in set_value:
tmp_value.append(base64.b64decode(item))
set_value = tmp_value
value = set_value value = set_value
elif set_type == '.template': elif set_type == '.template':
# Assuming set_value is a JSON object in this case # Assuming set_value is a JSON object in this case
value = json.loads(set_value) value = json.loads(set_value)
else:
# log debug info if not processed
if value == '----not processed----':
mylog('none', [f'[SETTINGS] ⚠ ERROR - set_type not handled:{set_type}']) mylog('none', [f'[SETTINGS] ⚠ ERROR - set_type not handled:{set_type}'])
mylog('none', [f'[SETTINGS] ⚠ ERROR - setting json:{json.dumps(setting)}']) mylog('none', [f'[SETTINGS] ⚠ ERROR - setting json:{json.dumps(set_value)}'])
value = ''
return value return value