Fix device card rendering with robust defaults and CSS fixes

- Add explicit default values for all card template variables
- Add try/catch for JSON.stringify
- Add !important CSS rules to ensure card body visibility
- Use ID selector for btDeviceListContent grid layout
- Add console logging for debugging device data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-01-21 17:31:48 +00:00
parent e3d9349d4b
commit bb660d02f5
2 changed files with 54 additions and 25 deletions
+21 -6
View File
@@ -557,18 +557,33 @@
/* ============================================ /* ============================================
DEVICE CARD GRID LAYOUT DEVICE CARD GRID LAYOUT
============================================ */ ============================================ */
.bt-device-list .wifi-device-list-content { #btDeviceListContent {
display: grid; display: grid !important;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)) !important;
gap: 12px; gap: 12px !important;
padding: 12px; padding: 12px !important;
} }
.bt-device-list .device-card { #btDeviceListContent .device-card {
margin: 0; margin: 0;
height: fit-content; height: fit-content;
} }
/* Ensure card body is visible */
.device-card .signal-card-body {
display: flex !important;
flex-direction: column;
gap: 8px;
}
.device-card .device-identity {
display: block !important;
}
.device-card .device-signal-row {
display: flex !important;
}
/* ============================================ /* ============================================
ENHANCED MODAL STYLES ENHANCED MODAL STYLES
============================================ */ ============================================ */
+33 -19
View File
@@ -154,11 +154,14 @@ const DeviceCard = (function() {
* Create a Bluetooth device card * Create a Bluetooth device card
*/ */
function createDeviceCard(device, options = {}) { function createDeviceCard(device, options = {}) {
// Debug: log received device data
console.log('[DeviceCard] Creating card for:', device.address, device);
const card = document.createElement('article'); const card = document.createElement('article');
card.className = 'signal-card device-card'; card.className = 'signal-card device-card';
card.dataset.deviceId = device.device_id; card.dataset.deviceId = device.device_id || '';
card.dataset.protocol = device.protocol; card.dataset.protocol = device.protocol || 'ble';
card.dataset.address = device.address; card.dataset.address = device.address || '';
// Add status classes // Add status classes
if (device.heuristic_flags && device.heuristic_flags.includes('new')) { if (device.heuristic_flags && device.heuristic_flags.includes('new')) {
@@ -168,13 +171,26 @@ const DeviceCard = (function() {
} }
// Store full device data for details modal // Store full device data for details modal
card.dataset.deviceData = JSON.stringify(device); try {
card.dataset.deviceData = JSON.stringify(device);
} catch (e) {
card.dataset.deviceData = '{}';
}
const relativeTime = formatRelativeTime(device.last_seen); const relativeTime = formatRelativeTime(device.last_seen) || 'Unknown';
const sparkline = createSparkline(device.rssi_history); const sparkline = createSparkline(device.rssi_history) || '';
const heuristicBadges = createHeuristicBadges(device.heuristic_flags); const heuristicBadges = createHeuristicBadges(device.heuristic_flags) || '';
const rangeBand = createRangeBand(device.range_band, device.range_confidence); const rangeBand = createRangeBand(device.range_band, device.range_confidence) || '';
const protocolBadge = createProtocolBadge(device.protocol); const protocolBadge = createProtocolBadge(device.protocol) || '';
// Build card with explicit defaults for all values
const deviceName = device.name || 'Unknown Device';
const deviceAddress = device.address || 'Unknown';
const addressType = device.address_type || 'unknown';
const rssiDisplay = device.rssi_current !== null && device.rssi_current !== undefined
? device.rssi_current + ' dBm' : '--';
const seenCount = device.seen_count || 0;
const inBaseline = device.in_baseline || false;
card.innerHTML = ` card.innerHTML = `
<div class="signal-card-header"> <div class="signal-card-header">
@@ -182,24 +198,22 @@ const DeviceCard = (function() {
${protocolBadge} ${protocolBadge}
${heuristicBadges} ${heuristicBadges}
</div> </div>
<span class="signal-status-pill" data-status="${device.in_baseline ? 'baseline' : 'new'}"> <span class="signal-status-pill" data-status="${inBaseline ? 'baseline' : 'new'}">
<span class="status-dot"></span> <span class="status-dot"></span>
${device.in_baseline ? 'Known' : 'New'} ${inBaseline ? 'Known' : 'New'}
</span> </span>
</div> </div>
<div class="signal-card-body"> <div class="signal-card-body">
<div class="device-identity"> <div class="device-identity">
<div class="device-name">${escapeHtml(device.name || 'Unknown Device')}</div> <div class="device-name">${escapeHtml(deviceName)}</div>
<div class="device-address"> <div class="device-address">
<span class="address-value">${escapeHtml(device.address)}</span> <span class="address-value">${escapeHtml(deviceAddress)}</span>
<span class="address-type">(${escapeHtml(device.address_type)})</span> <span class="address-type">(${escapeHtml(addressType)})</span>
</div> </div>
</div> </div>
<div class="device-signal-row"> <div class="device-signal-row">
<div class="rssi-display"> <div class="rssi-display">
<span class="rssi-current" title="Current RSSI"> <span class="rssi-current" title="Current RSSI">${rssiDisplay}</span>
${device.rssi_current !== null ? device.rssi_current + ' dBm' : '--'}
</span>
${sparkline} ${sparkline}
</div> </div>
${rangeBand} ${rangeBand}
@@ -213,9 +227,9 @@ const DeviceCard = (function() {
<div class="device-meta-row"> <div class="device-meta-row">
<span class="device-seen-count" title="Observation count"> <span class="device-seen-count" title="Observation count">
<span class="seen-icon">👁</span> <span class="seen-icon">👁</span>
${device.seen_count}× ${seenCount}×
</span> </span>
<span class="device-timestamp" data-timestamp="${escapeHtml(device.last_seen)}"> <span class="device-timestamp" data-timestamp="${escapeHtml(device.last_seen || '')}">
${escapeHtml(relativeTime)} ${escapeHtml(relativeTime)}
</span> </span>
</div> </div>