feat(frontend): show runtime state and auto/ack buttons on unit cards
This commit is contained in:
parent
31ccf49b75
commit
89023e867b
|
|
@ -74,6 +74,27 @@ async function selectUnit(unitId) {
|
||||||
await loadEvents();
|
await loadEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function runtimeBadge(runtime) {
|
||||||
|
if (!runtime) return '<span class="badge offline">OFFLINE</span>';
|
||||||
|
const stateLabels = {
|
||||||
|
stopped: 'STOPPED',
|
||||||
|
running: 'RUNNING',
|
||||||
|
distributor_running: 'DIST RUN',
|
||||||
|
fault_locked: 'FAULT',
|
||||||
|
comm_locked: 'COMM ERR',
|
||||||
|
};
|
||||||
|
const stateCls = {
|
||||||
|
stopped: '',
|
||||||
|
running: 'online',
|
||||||
|
distributor_running: 'online',
|
||||||
|
fault_locked: 'danger',
|
||||||
|
comm_locked: 'offline',
|
||||||
|
};
|
||||||
|
const label = stateLabels[runtime.state] ?? runtime.state;
|
||||||
|
const cls = stateCls[runtime.state] ?? '';
|
||||||
|
return `<span class="badge ${cls}">${label}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
export function renderUnits() {
|
export function renderUnits() {
|
||||||
dom.unitList.innerHTML = "";
|
dom.unitList.innerHTML = "";
|
||||||
|
|
||||||
|
|
@ -86,13 +107,15 @@ export function renderUnits() {
|
||||||
const card = document.createElement("div");
|
const card = document.createElement("div");
|
||||||
const selected = state.selectedUnitId === unit.id;
|
const selected = state.selectedUnitId === unit.id;
|
||||||
card.className = `list-item unit-card ${selected ? "selected" : ""}`;
|
card.className = `list-item unit-card ${selected ? "selected" : ""}`;
|
||||||
|
const runtime = state.runtimes.get(unit.id);
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<strong>${unit.code}</strong>
|
<strong>${unit.code}</strong>
|
||||||
<span class="badge ${unit.enabled ? "" : "offline"}">${unit.enabled ? "ENABLED" : "DISABLED"}</span>
|
${runtimeBadge(runtime)}
|
||||||
|
<span class="badge ${unit.enabled ? "" : "offline"}">${unit.enabled ? "EN" : "DIS"}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>${unit.name}</div>
|
<div>${unit.name}</div>
|
||||||
<div class="muted">设备 ${equipmentCount(unit.id)} 台</div>
|
<div class="muted">设备 ${equipmentCount(unit.id)} 台 | Acc ${runtime ? Math.floor(runtime.accumulated_run_sec / 1000) : 0}s</div>
|
||||||
<div class="muted">Run ${unit.run_time_sec}s / Stop ${unit.stop_time_sec}s / Acc ${unit.acc_time_sec}s / BL ${unit.bl_time_sec}s</div>
|
<div class="muted">Run ${unit.run_time_sec}s / Stop ${unit.stop_time_sec}s / Acc ${unit.acc_time_sec}s / BL ${unit.bl_time_sec}s</div>
|
||||||
<div class="row unit-card-actions"></div>
|
<div class="row unit-card-actions"></div>
|
||||||
`;
|
`;
|
||||||
|
|
@ -124,6 +147,32 @@ export function renderUnits() {
|
||||||
});
|
});
|
||||||
|
|
||||||
actions.append(editBtn, deleteBtn);
|
actions.append(editBtn, deleteBtn);
|
||||||
|
|
||||||
|
const isAutoOn = runtime?.auto_enabled;
|
||||||
|
const autoBtn = document.createElement("button");
|
||||||
|
autoBtn.className = isAutoOn ? "danger" : "secondary";
|
||||||
|
autoBtn.textContent = isAutoOn ? "Stop Auto" : "Start Auto";
|
||||||
|
autoBtn.title = isAutoOn ? "停止自动控制" : "启动自动控制";
|
||||||
|
autoBtn.addEventListener("click", (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const url = `/api/control/unit/${unit.id}/${isAutoOn ? "stop-auto" : "start-auto"}`;
|
||||||
|
apiFetch(url, { method: "POST" }).then(() => loadUnits()).catch(() => {});
|
||||||
|
});
|
||||||
|
actions.append(autoBtn);
|
||||||
|
|
||||||
|
if (runtime?.manual_ack_required) {
|
||||||
|
const ackBtn = document.createElement("button");
|
||||||
|
ackBtn.className = "danger";
|
||||||
|
ackBtn.textContent = "Ack Fault";
|
||||||
|
ackBtn.title = "人工确认解除故障锁定";
|
||||||
|
ackBtn.addEventListener("click", (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
apiFetch(`/api/control/unit/${unit.id}/ack-fault`, { method: "POST" })
|
||||||
|
.then(() => loadUnits()).catch(() => {});
|
||||||
|
});
|
||||||
|
actions.append(ackBtn);
|
||||||
|
}
|
||||||
|
|
||||||
dom.unitList.appendChild(card);
|
dom.unitList.appendChild(card);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue