diff --git a/Dockerfile b/Dockerfile index d0a5fce..e702b6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ sg3-utils \ lsscsi \ util-linux \ + ledmon \ && rm -rf /var/lib/apt/lists/* WORKDIR /app diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index a5c5f95..a8360f6 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -353,11 +353,35 @@ function TableView({ enclosure, onSelect, selectedSerial, t }) { } function DriveDetail({ slot, onClose, t }) { + const [ledLoading, setLedLoading] = useState(false); + const [ledState, setLedState] = useState(null); // "locate" | "off" | null + if (!slot) return null; const d = slot.drive || {}; const healthStatus = d.health_status || "healthy"; const c = t.health[healthStatus] || t.health.healthy; + const setLed = async (state) => { + setLedLoading(true); + try { + const res = await fetch(`${API_BASE}/api/drives/${slot.device}/led`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ state }), + }); + if (!res.ok) { + const err = await res.json().catch(() => ({})); + throw new Error(err.detail || `HTTP ${res.status}`); + } + setLedState(state); + } catch (err) { + console.error("LED control failed:", err); + setLedState(null); + } finally { + setLedLoading(false); + } + }; + const smartFields = [ ["SMART Status", d.smart_healthy === true ? "PASSED" : d.smart_healthy === false ? "FAILED" : "Unknown"], ["Temperature", d.temperature_c != null ? `${d.temperature_c}\u00B0C` : "\u2014"], @@ -504,7 +528,40 @@ function DriveDetail({ slot, onClose, t }) { })} -
+
+
+ + +