webui: organize config page with subtabs
This commit is contained in:
@@ -34,6 +34,7 @@ body{margin:0;background:var(--bg);color:var(--text);font-family:-apple-system,B
|
||||
h1{font-size:21px;margin:0}.sub{color:var(--muted);font-size:13px;margin-top:4px}
|
||||
.pill{border:1px solid var(--line);border-radius:999px;padding:7px 10px;color:var(--muted);font-size:12px;white-space:nowrap}
|
||||
.tabs{position:fixed;left:0;right:0;bottom:0;background:#080c11;border-top:1px solid var(--line);display:grid;grid-template-columns:repeat(3,1fr);z-index:10}
|
||||
.subtabs{display:flex;gap:8px;overflow-x:auto;padding:2px 0 12px;margin-bottom:4px}.subtabbtn{width:auto;white-space:nowrap;border:1px solid var(--line);background:#101722;color:var(--muted);padding:10px 12px;border-radius:999px;font-size:13px}.subtabbtn.active{background:#1f2b3c;color:var(--text);border-color:#3b536f}.configSubpage{display:none}.configSubpage.active{display:block}
|
||||
.tabbtn{border:0;border-radius:0;background:#080c11;color:var(--muted);padding:13px 8px;font-weight:800}
|
||||
.tabbtn.active{color:var(--text);background:#111923}
|
||||
.page{display:none}.page.active{display:block}
|
||||
@@ -173,6 +174,16 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
||||
</div>
|
||||
|
||||
<div id="configPage" class="page">
|
||||
<div class="subtabs">
|
||||
<button id="configTab-general" class="subtabbtn active" onclick="showConfigSubtab('general')">General</button>
|
||||
<button id="configTab-wifi" class="subtabbtn" onclick="showConfigSubtab('wifi')">WiFi / AP</button>
|
||||
<button id="configTab-relays" class="subtabbtn" onclick="showConfigSubtab('relays')">Relays</button>
|
||||
<button id="configTab-temps" class="subtabbtn" onclick="showConfigSubtab('temps')">Temperatures</button>
|
||||
<button id="configTab-bms" class="subtabbtn" onclick="showConfigSubtab('bms')">BMS</button>
|
||||
<button id="configTab-maintenance" class="subtabbtn" onclick="showConfigSubtab('maintenance')">Maintenance</button>
|
||||
</div>
|
||||
|
||||
<div id="config-general" class="configSubpage active">
|
||||
<div class="grid">
|
||||
<section class="card span12 configIntro">
|
||||
<div class="configGroupHeader">
|
||||
@@ -183,6 +194,23 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card span12">
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
<div class="configGroupTitle">General</div>
|
||||
<div class="configGroupHelp">Controller identity and general display settings.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<input id="deviceNameInput" placeholder="Device name">
|
||||
<button class="on" onclick="saveDeviceConfig()">Save Device Name</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="config-wifi" class="configSubpage">
|
||||
<div class="grid">
|
||||
<section class="card span12">
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
@@ -226,7 +254,11 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
||||
<button onclick="connectWifi()">Connect Now</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="config-relays" class="configSubpage">
|
||||
<div class="grid">
|
||||
<section class="card span12">
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
@@ -237,12 +269,16 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
||||
<div class="list" id="relayConfigList"></div>
|
||||
<button onclick="saveRelayConfig()">Save Relay Names</button>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="config-temps" class="configSubpage">
|
||||
<div class="grid">
|
||||
<section class="card span12">
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
<div class="configGroupTitle">Temperature Assignment</div>
|
||||
<div class="configGroupHelp">Scan probes, then assign a discovered sensor to a configured temp slot.</div>
|
||||
<div class="configGroupHelp">Scan probes, then assign discovered sensors to configured temp slots.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
@@ -252,58 +288,64 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
||||
</section>
|
||||
|
||||
<section class="card span12">
|
||||
<div class="label">Temperature Sensor Config</div>
|
||||
<div class="sub">Set how many temp sensors are enabled and rename each slot.</div>
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
<div class="configGroupTitle">Temperature Slots</div>
|
||||
<div class="configGroupHelp">Enable only the probes you use. Pick one weather sensor for the top badge.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<input id="tempEnabledCount" placeholder="Enabled sensor count, 0-8" inputmode="numeric">
|
||||
<input id="tempEnabledCount" placeholder="Enabled temp count" inputmode="numeric">
|
||||
<div id="tempConfigList" class="list"></div>
|
||||
<button onclick="saveTempConfig()">Save Temperature Config</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="config-bms" class="configSubpage">
|
||||
<div class="grid">
|
||||
<section class="card span12">
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
<div class="configGroupTitle">BMS</div>
|
||||
<div class="configGroupHelp">JBD/Xiaoxiang BLE settings. Do not change these unless pairing a different BMS.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<input id="bmsNameInput" placeholder="BMS name">
|
||||
<input id="bmsAddressInput" placeholder="BMS BLE address">
|
||||
<input id="bmsAddressTypeInput" placeholder="Address type: public or random">
|
||||
<button class="on" onclick="saveBmsFullConfig()">Save BMS Config</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card span12">
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
<div class="configGroupTitle">Device</div>
|
||||
<div class="configGroupHelp">Controller identity and BMS connection settings.</div>
|
||||
<div class="configGroupTitle">BMS Polling</div>
|
||||
<div class="configGroupHelp">Enable or disable BMS polling without changing BLE pairing details.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<input id="deviceNameInput" placeholder="Device name">
|
||||
<button onclick="saveDeviceConfig()">Save Device Name</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card span12">
|
||||
<div class="label">BMS Config</div>
|
||||
<div class="sub">Use this for initial setup, bench mode, or replacing the battery/BMS.</div>
|
||||
<div class="list">
|
||||
<input id="bmsNameInput" placeholder="BMS name">
|
||||
<input id="bmsAddressInput" placeholder="BMS BLE address">
|
||||
<input id="bmsAddressTypeInput" placeholder="Address type: public or random">
|
||||
<div class="btnrow">
|
||||
<button onclick="saveBmsFullConfig()">Save BMS</button>
|
||||
<button class="off" onclick="setBmsEnabled(false)">Disable BMS</button>
|
||||
</div>
|
||||
<div class="row"><span class="muted">BMS Polling</span><span class="v" id="bmsEnabledText">--</span></div>
|
||||
<div class="btnrow">
|
||||
<button onclick="setBmsEnabled(true)">Enable BMS</button>
|
||||
</div>
|
||||
<button class="off" onclick="setBmsEnabled(false)">Disable BMS</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card span12">
|
||||
<div class="label">System Actions</div>
|
||||
<div class="sub">Use carefully. Factory reset clears install-specific configuration.</div>
|
||||
<div class="btnrow">
|
||||
<button class="off" onclick="factoryReset()">Factory Reset</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div id="config-maintenance" class="configSubpage">
|
||||
<div class="grid">
|
||||
<section class="card span12">
|
||||
<div class="label">System</div>
|
||||
<div class="row"><span class="muted">Firmware</span><span class="v" id="fw">--</span></div>
|
||||
<div class="row"><span class="muted">Uptime</span><span class="v" id="uptime">--</span></div>
|
||||
<div class="row"><span class="muted">AP IP</span><span class="v" id="apIp">--</span></div>
|
||||
<div class="configGroupHeader">
|
||||
<div>
|
||||
<div class="configGroupTitle">Maintenance</div>
|
||||
<div class="configGroupHelp">Reset and recovery actions. These can disrupt the controller.</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="off" onclick="factoryReset()">Factory Reset Config</button>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@@ -474,6 +516,15 @@ function batteryTimeInfo(b){
|
||||
|
||||
return {label:"Battery time", value:"Idle"};
|
||||
}
|
||||
function showConfigSubtab(name){
|
||||
["general","wifi","relays","temps","bms","maintenance"].forEach(t=>{
|
||||
const page=$("config-"+t);
|
||||
const btn=$("configTab-"+t);
|
||||
if(page) page.classList.toggle("active",t===name);
|
||||
if(btn) btn.classList.toggle("active",t===name);
|
||||
});
|
||||
}
|
||||
|
||||
function showTab(name){
|
||||
["overview","battery","config"].forEach(t=>{
|
||||
$(t+"Page").classList.toggle("active",t===name);
|
||||
|
||||
@@ -352,3 +352,17 @@ def test_embedded_webui_config_page_is_grouped():
|
||||
assert "Relay Outputs" in source
|
||||
assert "Temperature Assignment" in source
|
||||
assert "Maintenance" in source
|
||||
|
||||
|
||||
def test_embedded_webui_config_subtabs():
|
||||
source = firmware_source()
|
||||
|
||||
assert "function showConfigSubtab(name)" in source
|
||||
assert "config-general" in source
|
||||
assert "config-wifi" in source
|
||||
assert "config-relays" in source
|
||||
assert "config-temps" in source
|
||||
assert "config-bms" in source
|
||||
assert "config-maintenance" in source
|
||||
assert "WiFi / AP" in source
|
||||
assert "Maintenance" in source
|
||||
|
||||
Reference in New Issue
Block a user