fix(ui): device row selection without full table rebuild; stable detail panel height

Made-with: Cursor
This commit is contained in:
PTah
2026-04-13 14:49:43 +10:00
parent 70fff4f0ea
commit 635876bbe3
+11 -2
View File
@@ -32,6 +32,8 @@
tr.fdb-row.selected { background: #dbeafe; box-shadow: inset 0.15em 0 0 #2563eb; } tr.fdb-row.selected { background: #dbeafe; box-shadow: inset 0.15em 0 0 #2563eb; }
.device-detail-table th, .device-detail-table td { border-bottom: 1px solid #e5e7eb; padding: 6px 8px; font-size: 13px; } .device-detail-table th, .device-detail-table td { border-bottom: 1px solid #e5e7eb; padding: 6px 8px; font-size: 13px; }
.subtable-wrap { overflow: auto; max-height: 200px; margin-top: 6px; border: 1px solid #e5e7eb; border-radius: 8px; } .subtable-wrap { overflow: auto; max-height: 200px; margin-top: 6px; border: 1px solid #e5e7eb; border-radius: 8px; }
/* Стабильная высота при «Загрузка…», меньше сдвиг графа/легенды под панелью деталей */
#deviceDetailPanel .subtable-wrap { min-height: 140px; }
</style> </style>
</head> </head>
<body> <body>
@@ -395,8 +397,14 @@
return `<tr class="device-row" data-ip="${dip}" title="Показать связи этого устройства"><td>${dip}</td><td>${escapeHtml(r.ping)}</td><td>${escapeHtml(r.name)}</td><td>${escapeHtml(r.snmp)}</td><td${lldpStyle}>${escapeHtml(r.lldp)}</td></tr>`; return `<tr class="device-row" data-ip="${dip}" title="Показать связи этого устройства"><td>${dip}</td><td>${escapeHtml(r.ping)}</td><td>${escapeHtml(r.name)}</td><td>${escapeHtml(r.snmp)}</td><td${lldpStyle}>${escapeHtml(r.lldp)}</td></tr>`;
}) })
.join(""); .join("");
updateDeviceRowSelectionHighlight();
}
/** Только подсветка строки — без пересборки таблицы (избегает дёрганья вёрстки/графа). */
function updateDeviceRowSelectionHighlight() {
deviceTableBody.querySelectorAll("tr.device-row").forEach((tr) => { deviceTableBody.querySelectorAll("tr.device-row").forEach((tr) => {
if (tr.getAttribute("data-ip") === selectedDeviceIP) tr.classList.add("selected"); const ip = tr.getAttribute("data-ip");
tr.classList.toggle("selected", ip != null && ip === selectedDeviceIP);
}); });
} }
@@ -417,6 +425,7 @@
deviceLldpTextTableBody.innerHTML = deviceLldpTextTableBody.innerHTML =
'<tr><td colspan="5" style="padding:10px;color:#64748b;">Выберите устройство и порт в Таблице 1.</td></tr>'; '<tr><td colspan="5" style="padding:10px;color:#64748b;">Выберите устройство и порт в Таблице 1.</td></tr>';
updateDeviceLinksSortIndicators(); updateDeviceLinksSortIndicators();
updateDeviceRowSelectionHighlight();
} }
function resolvedLabelRu(resolvedBy) { function resolvedLabelRu(resolvedBy) {
@@ -664,7 +673,7 @@
} }
selectedDeviceIP = ip; selectedDeviceIP = ip;
selectedDeviceLabel.textContent = ip; selectedDeviceLabel.textContent = ip;
renderDeviceTableBody(); updateDeviceRowSelectionHighlight();
deviceLinksTableBody.innerHTML = '<tr><td colspan="9" style="padding:10px;color:#64748b;">Загрузка…</td></tr>'; deviceLinksTableBody.innerHTML = '<tr><td colspan="9" style="padding:10px;color:#64748b;">Загрузка…</td></tr>';
deviceLldpTextTableBody.innerHTML = '<tr><td colspan="5" style="padding:10px;color:#64748b;">Загрузка…</td></tr>'; deviceLldpTextTableBody.innerHTML = '<tr><td colspan="5" style="padding:10px;color:#64748b;">Загрузка…</td></tr>';