diff --git a/AppImage/ProxMenux-1.2.1.2-beta.AppImage b/AppImage/ProxMenux-1.2.1.2-beta.AppImage index 1abc5eaa..f846c098 100755 Binary files a/AppImage/ProxMenux-1.2.1.2-beta.AppImage and b/AppImage/ProxMenux-1.2.1.2-beta.AppImage differ diff --git a/AppImage/ProxMenux-Monitor.AppImage.sha256 b/AppImage/ProxMenux-Monitor.AppImage.sha256 index ac203539..42aff57b 100644 --- a/AppImage/ProxMenux-Monitor.AppImage.sha256 +++ b/AppImage/ProxMenux-Monitor.AppImage.sha256 @@ -1 +1 @@ -25564b65c641c292c24e45336b49b68a57c1f87de83d2867945a9a1255a6e8a4 ProxMenux-1.2.1.2-beta.AppImage +91da610577f6c7254db6941685d901afb0a5de228f1fcac02c4b6e2e72a63683 ProxMenux-1.2.1.2-beta.AppImage diff --git a/AppImage/components/storage-overview.tsx b/AppImage/components/storage-overview.tsx index 638505cb..a3bba631 100644 --- a/AppImage/components/storage-overview.tsx +++ b/AppImage/components/storage-overview.tsx @@ -153,6 +153,42 @@ const formatStorage = (sizeInGB: number): string => { } } +// Translate the short ATA/SCSI error codes that appear inside `{ ... }` +// in a raw kernel observation (e.g. `error: { IDNF }`) into a one-line +// human description. Mirrors `_translate_ata_error` in +// notification_events.py — kept here so both the dialog and the printable +// SMART report can render a friendlier line under the raw message +// without round-tripping to the backend. Returns null when no recognised +// code is present, so the caller hides the extra line for non-ATA rows. +function translateAtaError(raw: string): string | null { + if (!raw) return null + const ATA_CODES: Record = { + IDNF: 'Sector address not found — possible bad sector or cable issue', + UNC: 'Uncorrectable read error — bad sector', + ABRT: 'Command aborted by drive', + AMNF: 'Address mark not found — surface damage', + TK0NF: 'Track 0 not found — drive hardware failure', + BBK: 'Bad block detected', + ICRC: 'Interface CRC error — cable or connector issue', + MC: 'Media changed', + MCR: 'Media change requested', + WP: 'Write protected', + } + const m = raw.match(/\{\s*([A-Z0-9 ]+)\s*\}/) + if (!m) return null + const codes = m[1].split(/\s+/).filter(Boolean) + const seen = new Set() + const out: string[] = [] + for (const c of codes) { + const desc = ATA_CODES[c] + if (desc && !seen.has(c)) { + seen.add(c) + out.push(desc) + } + } + return out.length ? out.join('; ') : null +} + export function StorageOverview() { // User-configurable disk temperature thresholds (Settings → Health // Monitor Thresholds). Until the API responds the hook returns @@ -373,42 +409,6 @@ export function StorageOverview() { const obsTypeLabel = (t: string) => ({ smart_error: 'SMART Error', io_error: 'I/O Error', filesystem_error: 'Filesystem Error', zfs_pool_error: 'ZFS Pool Error', connection_error: 'Connection Error' }[t] || t) - // Translate the short ATA/SCSI error codes that appear inside `{ ... }` - // in a raw kernel observation (e.g. `error: { IDNF }`) into a one-line - // human description. Mirrors `_translate_ata_error` in - // notification_events.py — kept here so the UI does not have to round-trip - // to the backend just to render a friendlier line under the raw message. - // Returns null when no recognised code is present, so the caller can hide - // the extra line for non-ATA observations. - const translateAtaError = (raw: string): string | null => { - if (!raw) return null - const ATA_CODES: Record = { - IDNF: 'Sector address not found — possible bad sector or cable issue', - UNC: 'Uncorrectable read error — bad sector', - ABRT: 'Command aborted by drive', - AMNF: 'Address mark not found — surface damage', - TK0NF: 'Track 0 not found — drive hardware failure', - BBK: 'Bad block detected', - ICRC: 'Interface CRC error — cable or connector issue', - MC: 'Media changed', - MCR: 'Media change requested', - WP: 'Write protected', - } - const m = raw.match(/\{\s*([A-Z0-9 ]+)\s*\}/) - if (!m) return null - const codes = m[1].split(/\s+/).filter(Boolean) - const seen = new Set() - const out: string[] = [] - for (const c of codes) { - const desc = ATA_CODES[c] - if (desc && !seen.has(c)) { - seen.add(c) - out.push(desc) - } - } - return out.length ? out.join('; ') : null - } - const getStorageTypeBadge = (type: string) => { const typeColors: Record = { pbs: "bg-purple-500/10 text-purple-500 border-purple-500/20", @@ -2753,6 +2753,7 @@ function openSmartReport(disk: DiskInfo, testStatus: SmartTestStatus, smartAttri
Raw Message:
${obs.raw_message || 'N/A'}
+ ${translateAtaError(obs.raw_message || '') ? `
↳ ${translateAtaError(obs.raw_message || '')}
` : ''}