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)