feat(feeder): add three-tab UI (ops / app-config / platform-config)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c961fc0298
commit
9955498e24
|
|
@ -133,6 +133,16 @@ body {
|
|||
grid-template-rows: 1fr 260px;
|
||||
}
|
||||
|
||||
.grid-app-config {
|
||||
display: grid;
|
||||
gap: 1px;
|
||||
height: calc(100vh - var(--topbar-h));
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
.grid-app-config .panel.app-config-main { grid-column: 1; grid-row: 1; }
|
||||
|
||||
/* config view slot assignments */
|
||||
.grid-config .panel.top-left { grid-column: 1; grid-row: 1; }
|
||||
.grid-config .panel.top-right { grid-column: 2 / 4; grid-row: 1; }
|
||||
|
|
@ -1315,6 +1325,11 @@ button.danger:hover { background: var(--danger-hover); }
|
|||
grid-template-rows: auto auto auto auto;
|
||||
height: auto;
|
||||
}
|
||||
.grid-app-config {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto;
|
||||
height: auto;
|
||||
}
|
||||
body { height: auto; overflow: auto; }
|
||||
.panel.top-left { min-height: 200px; }
|
||||
.panel.top-right { min-height: 300px; }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<header class="topbar">
|
||||
<div class="title">PLC Control</div>
|
||||
<div class="title">投煤器布料机控制系统</div>
|
||||
<div class="tab-bar">
|
||||
<button type="button" class="tab-btn active" id="tabOps">运维</button>
|
||||
<button type="button" class="tab-btn" id="tabConfig">配置</button>
|
||||
<button type="button" class="tab-btn" id="tabAppConfig">应用配置</button>
|
||||
<button type="button" class="tab-btn" id="tabConfig">平台配置</button>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<button type="button" class="secondary" id="openReadmeDoc">README.md</button>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
<section class="panel app-config-main">
|
||||
<div class="panel-head">
|
||||
<h2>控制单元配置</h2>
|
||||
<div class="toolbar">
|
||||
<button type="button" class="secondary" id="refreshUnitBtn2">刷新</button>
|
||||
<button type="button" id="newUnitBtn2">+ 新增</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list unit-config-list" id="unitConfigList"></div>
|
||||
</section>
|
||||
|
|
@ -15,8 +15,9 @@
|
|||
<div data-partial="/ui/html/points-panel.html"></div>
|
||||
<div data-partial="/ui/html/source-panel.html"></div>
|
||||
<div data-partial="/ui/html/log-stream-panel.html"></div>
|
||||
<div data-partial="/ui/html/logs-panel.html"></div>
|
||||
<div data-partial="/ui/html/chart-panel.html"></div>
|
||||
<div data-partial="/ui/html/unit-panel.html"></div>
|
||||
<div data-partial="/ui/html/logs-panel.html"></div>
|
||||
</main>
|
||||
|
||||
<div data-partial="/ui/html/modals.html"></div>
|
||||
|
|
|
|||
|
|
@ -35,29 +35,37 @@ import { loadSources, saveSource } from "./sources.js";
|
|||
import { 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" : "grid-config";
|
||||
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
|
||||
// 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 === "ops");
|
||||
if (el) el.classList.toggle("hidden", view !== "config");
|
||||
});
|
||||
// bottom-mid is log-stream in config, hidden in ops
|
||||
const logStreamPanel = main.querySelector(".panel.bottom-mid");
|
||||
if (logStreamPanel) logStreamPanel.classList.toggle("hidden", view === "ops");
|
||||
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 === "config");
|
||||
if (opsBottom) opsBottom.classList.toggle("hidden", view === "config");
|
||||
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();
|
||||
|
|
@ -71,6 +79,13 @@ function switchView(view) {
|
|||
} else {
|
||||
stopLogs();
|
||||
}
|
||||
|
||||
if (view === "app-config") {
|
||||
if (!_appConfigLoaded) {
|
||||
_appConfigLoaded = true;
|
||||
withStatus(loadUnits());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
|
|
@ -165,8 +180,12 @@ function bindEvents() {
|
|||
});
|
||||
|
||||
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()));
|
||||
dom.newUnitBtn2.addEventListener("click", openCreateUnitModal);
|
||||
|
||||
document.addEventListener("equipments-updated", () => {
|
||||
renderUnits();
|
||||
// Re-fetch units so embedded equipment data stays in sync with config changes.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export const dom = {
|
|||
batchStartAutoBtn: byId("batchStartAutoBtn"),
|
||||
batchStopAutoBtn: byId("batchStopAutoBtn"),
|
||||
tabOps: byId("tabOps"),
|
||||
tabAppConfig: byId("tabAppConfig"),
|
||||
tabConfig: byId("tabConfig"),
|
||||
opsUnitList: byId("opsUnitList"),
|
||||
opsEquipmentArea: byId("opsEquipmentArea"),
|
||||
|
|
@ -65,6 +66,9 @@ export const dom = {
|
|||
equipmentList: byId("equipmentList"),
|
||||
refreshUnitBtn: byId("refreshUnitBtn"),
|
||||
newUnitBtn: byId("newUnitBtn"),
|
||||
refreshUnitBtn2: byId("refreshUnitBtn2"),
|
||||
newUnitBtn2: byId("newUnitBtn2"),
|
||||
unitConfigList: byId("unitConfigList"),
|
||||
closeUnitModalBtn: byId("closeUnitModal"),
|
||||
closeEquipmentModalBtn: byId("closeEquipmentModal"),
|
||||
refreshEventBtn: byId("refreshEventBtn"),
|
||||
|
|
|
|||
Loading…
Reference in New Issue