fix(web): fetch all unit runtimes on page load
Root cause: state.runtimes was empty after refresh because the engine
only pushes UnitRuntimeChanged on state transitions — if the engine
is mid-wait-phase, no push occurs and badges show OFFLINE.
Fix: add GET /api/unit/runtimes batch endpoint (returns all known
runtimes as { unit_id: UnitRuntime }) and call it in parallel with
the unit list fetch inside loadUnits(), so runtime badges are correct
immediately after page load.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b3f92867bc
commit
42cdbbc0cc
|
|
@ -81,6 +81,10 @@ impl ControlRuntimeStore {
|
|||
.clone()
|
||||
}
|
||||
|
||||
pub async fn get_all(&self) -> HashMap<Uuid, UnitRuntime> {
|
||||
self.inner.read().await.clone()
|
||||
}
|
||||
|
||||
/// Wake the engine task for a unit (e.g., when auto_enabled or fault_locked changes).
|
||||
pub async fn notify_unit(&self, unit_id: Uuid) {
|
||||
if let Some(n) = self.notifiers.read().await.get(&unit_id) {
|
||||
|
|
|
|||
|
|
@ -509,3 +509,11 @@ pub async fn get_unit_runtime(
|
|||
let runtime = state.control_runtime.get_or_init(unit_id).await;
|
||||
Ok(Json(runtime))
|
||||
}
|
||||
|
||||
/// Returns all known runtimes as { unit_id: UnitRuntime }.
|
||||
/// Used by the frontend on page load to populate initial state.
|
||||
pub async fn get_all_unit_runtimes(
|
||||
State(state): State<AppState>,
|
||||
) -> impl IntoResponse {
|
||||
Json(state.control_runtime.get_all().await)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,6 +209,10 @@ fn build_router(state: AppState) -> Router {
|
|||
"/api/unit",
|
||||
get(handler::control::get_unit_list).post(handler::control::create_unit),
|
||||
)
|
||||
.route(
|
||||
"/api/unit/runtimes",
|
||||
get(handler::control::get_all_unit_runtimes),
|
||||
)
|
||||
.route(
|
||||
"/api/unit/{unit_id}",
|
||||
get(handler::control::get_unit)
|
||||
|
|
|
|||
|
|
@ -180,7 +180,10 @@ export function renderUnits() {
|
|||
}
|
||||
|
||||
export async function loadUnits() {
|
||||
const response = await apiFetch("/api/unit?page=1&page_size=-1");
|
||||
const [response, runtimes] = await Promise.all([
|
||||
apiFetch("/api/unit?page=1&page_size=-1"),
|
||||
apiFetch("/api/unit/runtimes").catch(() => ({})),
|
||||
]);
|
||||
state.units = response.data || [];
|
||||
state.unitMap = new Map(state.units.map((unit) => [unit.id, unit]));
|
||||
|
||||
|
|
@ -188,6 +191,10 @@ export async function loadUnits() {
|
|||
state.selectedUnitId = null;
|
||||
}
|
||||
|
||||
for (const [unitId, runtime] of Object.entries(runtimes)) {
|
||||
state.runtimes.set(unitId, runtime);
|
||||
}
|
||||
|
||||
renderUnits();
|
||||
renderUnitOptions(dom.equipmentUnitId?.value || "", dom.equipmentUnitId);
|
||||
renderUnitOptions(dom.equipmentBatchUnitId?.value || "", dom.equipmentBatchUnitId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue