211 lines
7.8 KiB
JavaScript
211 lines
7.8 KiB
JavaScript
import { withStatus } from "./api.js";
|
|
import { openChart, renderChart } from "./chart.js";
|
|
import { dom } from "./dom.js";
|
|
import { closeApiDocDrawer, openApiDocDrawer, openReadmeDrawer } from "./docs.js";
|
|
import { loadEvents } from "./events.js";
|
|
import {
|
|
clearPointBinding,
|
|
closeEquipmentModal,
|
|
loadEquipments,
|
|
openCreateEquipmentModal,
|
|
resetEquipmentForm,
|
|
saveEquipment,
|
|
} from "./equipment.js";
|
|
import { startPointSocket, startLogs, stopLogs } from "./logs.js";
|
|
import { startOps, renderOpsUnits, loadAllEquipmentCards } from "./ops.js";
|
|
import {
|
|
clearBatchBinding,
|
|
browseAndLoadTree,
|
|
clearSelectedPoints,
|
|
createPoints,
|
|
loadPoints,
|
|
loadTree,
|
|
openBatchBinding,
|
|
openPointCreateModal,
|
|
renderSelectedNodes,
|
|
saveBatchBinding,
|
|
savePointBinding,
|
|
updatePointFilterSummary,
|
|
updateSelectedPointSummary,
|
|
} from "./points.js";
|
|
import { state } from "./state.js";
|
|
import { loadSources, saveSource } from "./sources.js";
|
|
import { bindUnitEquipmentModalEvents, closeUnitModal, loadUnits, openCreateUnitModal, resetUnitForm, renderUnits, saveUnit } from "./units.js";
|
|
|
|
let _configLoaded = false;
|
|
let _appConfigLoaded = false;
|
|
|
|
function switchView(view) {
|
|
state.activeView = view;
|
|
const main = document.querySelector("main");
|
|
main.className =
|
|
view === "ops" ? "grid-ops" :
|
|
view === "app-config" ? "grid-app-config" :
|
|
"grid-config";
|
|
|
|
dom.tabOps.classList.toggle("active", view === "ops");
|
|
dom.tabAppConfig.classList.toggle("active", view === "app-config");
|
|
dom.tabConfig.classList.toggle("active", view === "config");
|
|
|
|
// config-only panels (platform config view)
|
|
["top-left", "top-right", "bottom-left", "bottom-right"].forEach((cls) => {
|
|
const el = main.querySelector(`.panel.${cls}`);
|
|
if (el) el.classList.toggle("hidden", view !== "config");
|
|
});
|
|
const logStreamPanel = main.querySelector(".panel.bottom-mid");
|
|
if (logStreamPanel) logStreamPanel.classList.toggle("hidden", view !== "config");
|
|
|
|
// ops-only panels
|
|
const opsMain = main.querySelector(".panel.ops-main");
|
|
const opsBottom = main.querySelector(".panel.ops-bottom");
|
|
if (opsMain) opsMain.classList.toggle("hidden", view !== "ops");
|
|
if (opsBottom) opsBottom.classList.toggle("hidden", view !== "ops");
|
|
|
|
// app-config-only panels
|
|
const appConfigMain = main.querySelector(".panel.app-config-main");
|
|
if (appConfigMain) appConfigMain.classList.toggle("hidden", view !== "app-config");
|
|
|
|
if (view === "config") {
|
|
startLogs();
|
|
if (!_configLoaded) {
|
|
_configLoaded = true;
|
|
withStatus((async () => {
|
|
await Promise.all([loadSources(), loadEquipments(), loadEvents()]);
|
|
await loadPoints();
|
|
})());
|
|
}
|
|
} else {
|
|
stopLogs();
|
|
}
|
|
|
|
if (view === "app-config") {
|
|
if (!_appConfigLoaded) {
|
|
_appConfigLoaded = true;
|
|
withStatus(Promise.all([loadUnits(), loadEquipments()]));
|
|
}
|
|
}
|
|
}
|
|
|
|
function bindEvents() {
|
|
dom.unitForm.addEventListener("submit", (event) => withStatus(saveUnit(event)));
|
|
dom.sourceForm.addEventListener("submit", (event) => withStatus(saveSource(event)));
|
|
dom.equipmentForm.addEventListener("submit", (event) => withStatus(saveEquipment(event)));
|
|
dom.pointBindingForm.addEventListener("submit", (event) => withStatus(savePointBinding(event)));
|
|
dom.batchBindingForm.addEventListener("submit", (event) => withStatus(saveBatchBinding(event)));
|
|
|
|
dom.unitResetBtn.addEventListener("click", resetUnitForm);
|
|
if (dom.refreshUnitBtn) dom.refreshUnitBtn.addEventListener("click", () => withStatus(loadUnits().then(loadEvents)));
|
|
if (dom.newUnitBtn) dom.newUnitBtn.addEventListener("click", openCreateUnitModal);
|
|
dom.closeUnitModalBtn.addEventListener("click", closeUnitModal);
|
|
|
|
dom.sourceResetBtn.addEventListener("click", () => dom.sourceForm.reset());
|
|
dom.equipmentResetBtn.addEventListener("click", resetEquipmentForm);
|
|
dom.refreshEquipmentBtn.addEventListener("click", () => withStatus(loadEquipments()));
|
|
dom.newEquipmentBtn.addEventListener("click", openCreateEquipmentModal);
|
|
dom.closeEquipmentModalBtn.addEventListener("click", closeEquipmentModal);
|
|
dom.openPointModalBtn.addEventListener("click", openPointCreateModal);
|
|
dom.pointSourceSelect.addEventListener("change", () => {
|
|
dom.nodeTree.innerHTML = '<div class="muted">点击"加载节点"获取节点树</div>';
|
|
dom.pointSourceNodeCount.textContent = "节点: 0";
|
|
});
|
|
dom.browseNodesBtn.addEventListener("click", () => withStatus(browseAndLoadTree()));
|
|
dom.refreshTreeBtn.addEventListener("click", () => withStatus(loadTree()));
|
|
dom.createPointsBtn.addEventListener("click", () => withStatus(createPoints()));
|
|
dom.closeModalBtn.addEventListener("click", () => dom.pointModal.classList.add("hidden"));
|
|
|
|
dom.openSourceFormBtn.addEventListener("click", () => {
|
|
dom.sourceForm.reset();
|
|
dom.sourceId.value = "";
|
|
dom.sourceModal.classList.remove("hidden");
|
|
});
|
|
dom.closeSourceModalBtn.addEventListener("click", () => dom.sourceModal.classList.add("hidden"));
|
|
|
|
dom.clearPointBindingBtn.addEventListener("click", () => withStatus(clearPointBinding()));
|
|
dom.closePointBindingModalBtn.addEventListener("click", () => {
|
|
dom.pointBindingModal.classList.add("hidden");
|
|
});
|
|
|
|
dom.openBatchBindingBtn.addEventListener("click", openBatchBinding);
|
|
dom.clearSelectedPointsBtn.addEventListener("click", clearSelectedPoints);
|
|
dom.closeBatchBindingModalBtn.addEventListener("click", () => {
|
|
dom.batchBindingModal.classList.add("hidden");
|
|
});
|
|
dom.clearBatchBindingBtn.addEventListener("click", () => withStatus(clearBatchBinding()));
|
|
|
|
dom.toggleAllPoints.addEventListener("change", () => {
|
|
const checked = dom.toggleAllPoints.checked;
|
|
dom.pointList.querySelectorAll('input[data-point-select="true"]').forEach((input) => {
|
|
input.checked = checked;
|
|
input.dispatchEvent(new Event("change"));
|
|
});
|
|
});
|
|
|
|
dom.openReadmeDocBtn.addEventListener("click", () => withStatus(openReadmeDrawer()));
|
|
dom.openApiDocBtn.addEventListener("click", () => withStatus(openApiDocDrawer()));
|
|
dom.closeApiDocBtn.addEventListener("click", closeApiDocDrawer);
|
|
dom.refreshEventBtn.addEventListener("click", () => withStatus(loadEvents()));
|
|
|
|
dom.refreshChartBtn.addEventListener("click", () => {
|
|
if (!state.chartPointId) {
|
|
return;
|
|
}
|
|
withStatus(openChart(state.chartPointId, state.chartPointName));
|
|
});
|
|
|
|
dom.prevPointsBtn.addEventListener("click", () => {
|
|
if (state.pointsPage > 1) {
|
|
state.pointsPage -= 1;
|
|
withStatus(loadPoints());
|
|
}
|
|
});
|
|
|
|
dom.nextPointsBtn.addEventListener("click", () => {
|
|
const totalPages = Math.max(1, Math.ceil(state.pointsTotal / state.pointsPageSize));
|
|
if (state.pointsPage < totalPages) {
|
|
state.pointsPage += 1;
|
|
withStatus(loadPoints());
|
|
}
|
|
});
|
|
|
|
dom.equipmentKeyword.addEventListener("keydown", (event) => {
|
|
if (event.key === "Enter") {
|
|
event.preventDefault();
|
|
withStatus(loadEquipments());
|
|
}
|
|
});
|
|
|
|
dom.tabOps.addEventListener("click", () => switchView("ops"));
|
|
dom.tabAppConfig.addEventListener("click", () => switchView("app-config"));
|
|
dom.tabConfig.addEventListener("click", () => switchView("config"));
|
|
|
|
dom.refreshUnitBtn2.addEventListener("click", () => withStatus(loadUnits().then(loadEvents)));
|
|
dom.newUnitBtn2.addEventListener("click", openCreateUnitModal);
|
|
bindUnitEquipmentModalEvents();
|
|
|
|
document.addEventListener("equipments-updated", () => {
|
|
renderUnits();
|
|
// Re-fetch units so embedded equipment data stays in sync with config changes.
|
|
loadUnits().catch(() => {});
|
|
});
|
|
|
|
document.addEventListener("units-loaded", () => {
|
|
renderOpsUnits();
|
|
if (!state.selectedOpsUnitId) loadAllEquipmentCards();
|
|
});
|
|
}
|
|
|
|
async function bootstrap() {
|
|
bindEvents();
|
|
switchView("ops");
|
|
renderSelectedNodes();
|
|
updateSelectedPointSummary();
|
|
updatePointFilterSummary();
|
|
renderChart();
|
|
startPointSocket();
|
|
|
|
await withStatus(Promise.all([loadUnits(), loadEvents()]));
|
|
startOps();
|
|
}
|
|
|
|
bootstrap();
|