import { apiFetch } from "./api.js"; import { dom } from "./dom.js"; import { renderRoleOptions } from "./roles.js"; import { clearSelectedPoints, loadPoints, updatePointFilterSummary } from "./points.js"; import { state } from "./state.js"; function equipmentOf(item) { return item && item.equipment ? item.equipment : item; } export function renderBindingEquipmentOptions(selected = "", target = dom.bindingEquipmentId) { const options = ['']; state.equipments.forEach((item) => { const equipment = equipmentOf(item); const isSelected = equipment.id === selected ? "selected" : ""; options.push( ``, ); }); target.innerHTML = options.join(""); } export function renderBatchBindingDefaults() { renderBindingEquipmentOptions("", dom.batchBindingEquipmentId); dom.batchBindingSignalRole.innerHTML = renderRoleOptions(""); } export function resetEquipmentForm() { dom.equipmentForm.reset(); dom.equipmentId.value = ""; } function openEquipmentModal() { dom.equipmentModal.classList.remove("hidden"); } export function closeEquipmentModal() { dom.equipmentModal.classList.add("hidden"); } export function openCreateEquipmentModal() { resetEquipmentForm(); openEquipmentModal(); } function openEditEquipmentModal(equipment) { dom.equipmentId.value = equipment.id || ""; dom.equipmentCode.value = equipment.code || ""; dom.equipmentName.value = equipment.name || ""; dom.equipmentKind.value = equipment.kind || ""; dom.equipmentDescription.value = equipment.description || ""; openEquipmentModal(); } async function selectEquipment(equipmentId) { state.selectedEquipmentId = state.selectedEquipmentId === equipmentId ? null : equipmentId; state.pointsPage = 1; clearSelectedPoints(); renderEquipments(); updatePointFilterSummary(); await loadPoints(); } export function clearEquipmentFilter() { state.selectedEquipmentId = null; state.pointsPage = 1; renderEquipments(); updatePointFilterSummary(); return loadPoints(); } export function renderEquipments() { dom.equipmentList.innerHTML = ""; const activeEquipment = state.selectedEquipmentId ? state.equipmentMap.get(state.selectedEquipmentId) || null : null; dom.clearEquipmentFilterBtn.textContent = activeEquipment ? `设备筛选: ${activeEquipment.name}` : "设备筛选: 全部"; if (!state.equipments.length) { dom.equipmentList.innerHTML = '
No equipment
'; return; } state.equipments.forEach((item) => { const equipment = equipmentOf(item); const box = document.createElement("div"); box.className = `list-item equipment-card ${state.selectedEquipmentId === equipment.id ? "selected" : ""}`; box.innerHTML = `
${equipment.code} ${item.point_count ?? 0} pts
${equipment.name}
${equipment.kind || "No type"}
`; box.addEventListener("click", () => { selectEquipment(equipment.id).catch((error) => { dom.statusText.textContent = error.message; }); }); const actionRow = box.querySelector(".equipment-card-actions"); const editBtn = document.createElement("button"); editBtn.className = "secondary"; editBtn.textContent = "Edit"; editBtn.addEventListener("click", (event) => { event.stopPropagation(); openEditEquipmentModal(equipment); }); const deleteBtn = document.createElement("button"); deleteBtn.className = "danger"; deleteBtn.textContent = "Delete"; deleteBtn.addEventListener("click", (event) => { event.stopPropagation(); deleteEquipment(equipment.id).catch((error) => { dom.statusText.textContent = error.message; }); }); actionRow.append(editBtn, deleteBtn); dom.equipmentList.appendChild(box); }); } export async function loadEquipments() { const keyword = dom.equipmentKeyword.value.trim(); const query = keyword ? `?page=1&page_size=-1&keyword=${encodeURIComponent(keyword)}` : "?page=1&page_size=-1"; const data = await apiFetch(`/api/equipment${query}`); state.equipments = data.data || []; state.equipmentMap = new Map( state.equipments.map((item) => { const equipment = equipmentOf(item); return [equipment.id, equipment]; }), ); renderBindingEquipmentOptions(); renderBatchBindingDefaults(); if (state.selectedEquipmentId && !state.equipmentMap.has(state.selectedEquipmentId)) { state.selectedEquipmentId = null; } renderEquipments(); updatePointFilterSummary(); } export async function saveEquipment(event) { event.preventDefault(); const payload = { code: dom.equipmentCode.value.trim(), name: dom.equipmentName.value.trim(), kind: dom.equipmentKind.value.trim() || null, description: dom.equipmentDescription.value.trim() || null, }; const id = dom.equipmentId.value; const result = await apiFetch(id ? `/api/equipment/${id}` : "/api/equipment", { method: id ? "PUT" : "POST", body: JSON.stringify(payload), }); closeEquipmentModal(); await loadEquipments(); if (!id && result?.id) { state.selectedEquipmentId = result.id; } renderEquipments(); updatePointFilterSummary(); await loadPoints(); } export async function deleteEquipment(equipmentId) { if (!window.confirm("Delete this equipment?")) { return; } await apiFetch(`/api/equipment/${equipmentId}`, { method: "DELETE" }); if (state.selectedEquipmentId === equipmentId) { state.selectedEquipmentId = null; } resetEquipmentForm(); closeEquipmentModal(); clearSelectedPoints(); await loadEquipments(); await loadPoints(); } export async function clearPointBinding(pointId = dom.bindingPointId.value) { await apiFetch(`/api/point/${pointId}`, { method: "PUT", body: JSON.stringify({ equipment_id: null, signal_role: null }), }); dom.pointBindingModal.classList.add("hidden"); await loadEquipments(); await loadPoints(); }