From cafa36f627f693180f907b85c305c4711edf1045 Mon Sep 17 00:00:00 2001 From: "Jokob @NetAlertX" <96159884+jokob-sk@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:57:48 +0000 Subject: [PATCH] feat: Enhance readonly input styles and improve device data handling --- front/css/app.css | 16 +++++++------ front/css/dark-patch.css | 22 ++++++++++++++---- front/css/system-dark-patch.css | 15 ++++++++++++- front/deviceDetailsEdit.php | 40 +++++++++++++++++++++------------ server/scan/device_handling.py | 12 +++++++++- 5 files changed, 78 insertions(+), 27 deletions(-) diff --git a/front/css/app.css b/front/css/app.css index 7371c5d7..bba5e5d0 100755 --- a/front/css/app.css +++ b/front/css/app.css @@ -1216,12 +1216,14 @@ height: 50px; width: 20%; } -input[readonly] { - /* Apply styles to the readonly input */ - background-color: #646566 !important; - color: #e6e6e6; +input[readonly], +textarea[readonly], +.form-control[readonly] { + background-color: #f4f6f8; + border-color: #d2d6de; + color: #6b7280; cursor: not-allowed; - } +} .interactable-option:hover::before { opacity: 1; @@ -1491,12 +1493,12 @@ input[readonly] { } .select2-container--default .select2-selection--multiple { - background-color:#606060 !important; + background-color:#ffffff !important; } .select2-container .select2-dropdown { - background-color:#606060 !important; + background-color:#ffffff !important; } .select2-container--default .select2-selection--multiple, diff --git a/front/css/dark-patch.css b/front/css/dark-patch.css index c3649b65..50f51051 100755 --- a/front/css/dark-patch.css +++ b/front/css/dark-patch.css @@ -509,11 +509,20 @@ div.dataTables_wrapper div.dataTables_length select { border: 1px solid #3d444b; } .form-control[disabled], -.form-control[readonly], fieldset[disabled] .form-control { background-color: #353c42; opacity: 1; } +input[readonly], +textarea[readonly], +.form-control[readonly] { + background-color: #545659 !important; + border-color: #3d444b; + color: #888a8c; + cursor: not-allowed; + opacity: 1; +} + .navbar-custom-menu > .navbar-nav > li > .dropdown-menu { background-color: #4c5761; color: #bec5cb; @@ -682,7 +691,7 @@ table.dataTable tbody tr.selected, table.dataTable tbody tr .selected .db_tools_table_cell_b:nth-child(1) {background: #272c30} .db_tools_table_cell_b:nth-child(2) {background: #272c30} -.db_info_table { +.db_info_table { display: table; border-spacing: 0em; font-weight: 400; @@ -746,7 +755,7 @@ table.dataTable tbody tr.selected, table.dataTable tbody tr .selected .small-box:hover .icon { font-size: 3em; } -.small-box .icon { +.small-box .icon { top: 0.01em; font-size: 3.25em; } @@ -774,6 +783,11 @@ table.dataTable tbody tr.selected, table.dataTable tbody tr .selected border-color: #3d444b !important; } +.select2-container--default .select2-selection--multiple { + background-color: #353c42 !important; + color: #bec5cb; +} + .select2-container--default .select2-selection--single .select2-selection__rendered .custom-chip { color: #bec5cb; @@ -791,7 +805,7 @@ table.dataTable tbody tr.selected, table.dataTable tbody tr .selected .thresholdFormControl { - color:#000; + color:#000; } .btn:hover diff --git a/front/css/system-dark-patch.css b/front/css/system-dark-patch.css index 87ab4556..2b809310 100755 --- a/front/css/system-dark-patch.css +++ b/front/css/system-dark-patch.css @@ -512,11 +512,19 @@ border: 1px solid #3d444b; } .form-control[disabled], - .form-control[readonly], fieldset[disabled] .form-control { background-color: #353c42; opacity: 1; } + input[readonly], + textarea[readonly], + .form-control[readonly] { + background-color: #2f353b !important; + border-color: #3d444b; + color: #c7cdd3; + cursor: not-allowed; + opacity: 1; + } .navbar-custom-menu > .navbar-nav > li > .dropdown-menu { background-color: #4c5761; color: #bec5cb; @@ -776,6 +784,11 @@ border-color: #3d444b !important; } + .select2-container--default .select2-selection--multiple { + background-color: #353c42 !important; + color: #bec5cb; + } + .select2-container--default .select2-selection--single .select2-selection__rendered .custom-chip { color: #bec5cb; diff --git a/front/deviceDetailsEdit.php b/front/deviceDetailsEdit.php index 73703e82..d36a343f 100755 --- a/front/deviceDetailsEdit.php +++ b/front/deviceDetailsEdit.php @@ -273,10 +273,12 @@ function getDeviceData() { // Add lock/unlock button for tracked fields (not for new devices) const fieldName = setting.setKey.replace('NEWDEV_', ''); - if (trackedFields[fieldName] && mac != "new") { - const sourceField = fieldName + "Source"; - const currentSource = deviceData[sourceField] || "UNKNOWN"; - const isLocked = currentSource === "LOCKED"; + const sourceField = fieldName + "Source"; + const currentSource = (deviceData[sourceField] ?? "").toString().trim(); + const normalizedSource = currentSource.toLowerCase(); + const hasSourceValue = currentSource !== "" && normalizedSource !== "null"; + const isLocked = currentSource === "LOCKED"; + if (trackedFields[fieldName] && fieldName !== "devFQDN" && mac != "new") { const lockIcon = isLocked ? "fa-lock" : "fa-lock-open"; const lockTitle = isLocked ? getString("FieldLock_Unlock_Tooltip") : getString("FieldLock_Lock_Tooltip"); inlineControl += ` `; + if (isLocked) { + if (!disabledFields.includes(setting.setKey)) { + disabledFields.push(setting.setKey); + } + } } // Add source indicator for tracked fields - const fieldName2 = setting.setKey.replace('NEWDEV_', ''); - if (trackedFields[fieldName2] && mac != "new") { - const sourceField = fieldName2 + "Source"; - const currentSource = deviceData[sourceField] || "UNKNOWN"; + if (trackedFields[fieldName] && mac != "new" && hasSourceValue) { const sourceTitle = getString("FieldLock_Source_Label") + currentSource; const sourceColor = currentSource === "USER" ? "text-warning" : (currentSource === "LOCKED" ? "text-danger" : "text-muted"); inlineControl += ` @@ -561,7 +565,7 @@ function toggleFieldLock(mac, fieldName) { // Get current source value const sourceField = fieldName + "Source"; - const currentSource = deviceData[sourceField] || "UNKNOWN"; + const currentSource = (deviceData[sourceField] ?? "").toString().trim(); const shouldLock = currentSource !== "LOCKED"; const payload = { @@ -597,14 +601,22 @@ function toggleFieldLock(mac, fieldName) { // Update local source state deviceData[sourceField] = shouldLock ? "LOCKED" : ""; + const fieldKey = `NEWDEV_${fieldName}`; + const fieldInput = $(`#${fieldKey}`); + fieldInput.prop("readonly", shouldLock); + // Update source indicator const sourceIndicator = lockBtn.next(); if (sourceIndicator.hasClass("input-group-addon")) { - const sourceValue = shouldLock ? "LOCKED" : "UNKNOWN"; - const sourceClass = shouldLock ? "input-group-addon text-danger" : "input-group-addon pointer text-muted"; - sourceIndicator.text(sourceValue); - sourceIndicator.attr("class", sourceClass); - sourceIndicator.attr("title", getString("FieldLock_Source_Label") + sourceValue); + if (shouldLock) { + const sourceValue = "LOCKED"; + const sourceClass = "input-group-addon pointer text-danger"; + sourceIndicator.text(sourceValue); + sourceIndicator.attr("class", sourceClass); + sourceIndicator.attr("title", getString("FieldLock_Source_Label") + sourceValue); + } else { + sourceIndicator.remove(); + } } showMessage(shouldLock ? getString("FieldLock_Locked") : getString("FieldLock_Unlocked"), 3000, "modal_green"); diff --git a/server/scan/device_handling.py b/server/scan/device_handling.py index 3af9100f..4737f47b 100755 --- a/server/scan/device_handling.py +++ b/server/scan/device_handling.py @@ -907,9 +907,17 @@ def create_new_devices(db): raw_name = str(cur_Name).strip() if cur_Name else "" raw_vendor = str(cur_Vendor).strip() if cur_Vendor else "" raw_ip = str(cur_IP).strip() if cur_IP else "" + if raw_ip.lower() in ("null", "(unknown)"): + raw_ip = "" raw_ssid = str(cur_SSID).strip() if cur_SSID else "" - raw_parent_mac = cur_NetworkNodeMAC.strip() if cur_NetworkNodeMAC else "" + if raw_ssid.lower() in ("null", "(unknown)"): + raw_ssid = "" + raw_parent_mac = str(cur_NetworkNodeMAC).strip() if cur_NetworkNodeMAC else "" + if raw_parent_mac.lower() in ("null", "(unknown)"): + raw_parent_mac = "" raw_parent_port = str(cur_PORT).strip() if cur_PORT else "" + if raw_parent_port.lower() in ("null", "(unknown)"): + raw_parent_port = "" # Handle NoneType cur_Name = raw_name if raw_name else "(unknown)" @@ -934,6 +942,8 @@ def create_new_devices(db): # Derive primary IP family values cur_IP = raw_ip + cur_SSID = raw_ssid + cur_PORT = raw_parent_port cur_IP_normalized = check_IP_format(cur_IP) if ":" not in cur_IP else cur_IP # Validate IPv6 addresses using format_ip_long for consistency (do not store integer result)