Implement full JBOD monitor frontend from design JSX
- Dark/light theme toggle, grid/table view toggle - Expanded DriveHealthSummary with wwn, firmware, capacity, SMART counters, and computed health_status field - Drive detail modal with identity, WWN, ZFS membership, SMART health - 30s auto-refresh
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -40,11 +40,18 @@ class DriveHealthSummary(BaseModel):
|
|||||||
device: str
|
device: str
|
||||||
model: str | None = None
|
model: str | None = None
|
||||||
serial: str | None = None
|
serial: str | None = None
|
||||||
|
wwn: str | None = None
|
||||||
|
firmware: str | None = None
|
||||||
|
capacity_bytes: int | None = None
|
||||||
smart_healthy: bool | None = None
|
smart_healthy: bool | None = None
|
||||||
smart_supported: bool = True
|
smart_supported: bool = True
|
||||||
temperature_c: int | None = None
|
temperature_c: int | None = None
|
||||||
power_on_hours: int | None = None
|
power_on_hours: int | None = None
|
||||||
|
reallocated_sectors: int | None = None
|
||||||
|
pending_sectors: int | None = None
|
||||||
|
uncorrectable_errors: int | None = None
|
||||||
zfs_pool: str | None = None
|
zfs_pool: str | None = None
|
||||||
|
health_status: str = "healthy"
|
||||||
|
|
||||||
|
|
||||||
class SlotWithDrive(BaseModel):
|
class SlotWithDrive(BaseModel):
|
||||||
|
|||||||
@@ -68,15 +68,33 @@ async def get_overview():
|
|||||||
if sd.get("uncorrectable_errors") and sd["uncorrectable_errors"] > 0:
|
if sd.get("uncorrectable_errors") and sd["uncorrectable_errors"] > 0:
|
||||||
warnings += 1
|
warnings += 1
|
||||||
|
|
||||||
|
# Compute health_status for frontend
|
||||||
|
realloc = sd.get("reallocated_sectors") or 0
|
||||||
|
pending = sd.get("pending_sectors") or 0
|
||||||
|
unc = sd.get("uncorrectable_errors") or 0
|
||||||
|
if healthy is False:
|
||||||
|
health_status = "error"
|
||||||
|
elif realloc > 0 or pending > 0 or unc > 0 or (healthy is None and sd.get("smart_supported", True)):
|
||||||
|
health_status = "warning"
|
||||||
|
else:
|
||||||
|
health_status = "healthy"
|
||||||
|
|
||||||
drive_summary = DriveHealthSummary(
|
drive_summary = DriveHealthSummary(
|
||||||
device=sd["device"],
|
device=sd["device"],
|
||||||
model=sd.get("model"),
|
model=sd.get("model"),
|
||||||
serial=sd.get("serial"),
|
serial=sd.get("serial"),
|
||||||
|
wwn=sd.get("wwn"),
|
||||||
|
firmware=sd.get("firmware"),
|
||||||
|
capacity_bytes=sd.get("capacity_bytes"),
|
||||||
smart_healthy=healthy,
|
smart_healthy=healthy,
|
||||||
smart_supported=sd.get("smart_supported", True),
|
smart_supported=sd.get("smart_supported", True),
|
||||||
temperature_c=sd.get("temperature_c"),
|
temperature_c=sd.get("temperature_c"),
|
||||||
power_on_hours=sd.get("power_on_hours"),
|
power_on_hours=sd.get("power_on_hours"),
|
||||||
|
reallocated_sectors=sd.get("reallocated_sectors"),
|
||||||
|
pending_sectors=sd.get("pending_sectors"),
|
||||||
|
uncorrectable_errors=sd.get("uncorrectable_errors"),
|
||||||
zfs_pool=pool_map.get(sd["device"]),
|
zfs_pool=pool_map.get(sd["device"]),
|
||||||
|
health_status=health_status,
|
||||||
)
|
)
|
||||||
elif s["populated"]:
|
elif s["populated"]:
|
||||||
total_drives += 1
|
total_drives += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user