safesight-control/internal/web/ui/templates/template_settings.html

98 lines
3.8 KiB
HTML

{{define "template_settings"}}
{{template "asset_tabs" .}}
{{if .TuningItems}}
<div class="card">
<div class="section-title">
<h2 class="title-with-icon">{{icon "edit"}}<span>{{.AssetTemplate.Name}} · 参数调整</span></h2>
</div>
<p class="hint">修改参数后,点击「保存并下发」将更新所有使用此模板的设备。</p>
</div>
<form method="POST" action="/assets/templates/{{.AssetTemplate.Name}}/settings">
{{range $group, $items := .TuningGroups}}
<div class="card">
<h3 class="title-with-icon">{{icon "edit"}}<span>{{$group}}</span></h3>
<div class="tuning-list">
{{range $items}}
<div class="tuning-item">
<label class="tuning-label">{{.Label}}</label>
<div class="tuning-control">
<input type="range" name="tune_{{.Path}}" value="{{printf "%.4f" .Value}}" min="{{.Min}}" max="{{.Max}}" step="{{.Step}}"
oninput="this.nextElementSibling.value=Number(this.value).toFixed({{if eq .Step 1.0}}0{{else if eq .Step 0.05}}2{{else}}1{{end}})+'{{.Unit}}'">
<output>{{printf "%.4f" .Value}}{{.Unit}}</output>
</div>
</div>
{{end}}
</div>
</div>
{{end}}
<div class="card" id="affected-devices" style="display:none">
<h3 class="title-with-icon">{{icon "device"}}<span>受影响设备 (<span id="affected-count">0</span>)</span></h3>
<div id="affected-list" class="device-list"></div>
</div>
<div class="card actions">
<button type="submit" class="btn primary" name="action" value="save">保存参数</button>
<button type="submit" class="btn primary" name="action" value="deploy" id="btn-deploy" disabled>保存并下发</button>
<a class="btn secondary" href="/assets/templates/{{.AssetTemplate.Name}}">返回</a>
</div>
</form>
<script>
document.querySelector('form').addEventListener('submit', async function(e) {
const btn = e.submitter;
if (!btn || btn.value !== 'deploy') return;
e.preventDefault();
const form = this;
const fd = new FormData(form);
fd.set('action', 'preview');
const resp = await fetch(form.action, { method: 'POST', body: fd });
const data = await resp.json();
const div = document.getElementById('affected-devices');
const count = document.getElementById('affected-count');
const list = document.getElementById('affected-list');
const deployBtn = document.getElementById('btn-deploy');
div.style.display = 'block';
count.textContent = data.devices ? data.devices.length : 0;
if (data.devices && data.devices.length > 0) {
deployBtn.disabled = false;
list.innerHTML = data.devices.map(function(d) {
return '<span class="pill ok device-item">' + d + '</span>';
}).join('');
} else {
deployBtn.disabled = true;
list.innerHTML = '<p class="hint">没有设备使用此模板。请先在运行看板中为设备分配此模板。</p>';
}
// Store affected devices for final submit
document.getElementById('affected-ids').value = (data.devices || []).join(',');
document.getElementById('deploy-flag').value = '1';
});
document.getElementById('btn-deploy').addEventListener('click', function() {
if (document.getElementById('affected-ids').value) {
document.getElementById('deploy-flag').value = '1';
document.querySelector('form').submit();
}
});
</script>
<input type="hidden" name="affected_ids" id="affected-ids" value="">
<input type="hidden" name="do_deploy" id="deploy-flag" value="0">
{{else}}
<div class="card">
<div class="section-title">
<h2 class="title-with-icon">{{icon "edit"}}<span>{{.AssetTemplate.Name}} · 参数调整</span></h2>
</div>
<p class="hint">该模板没有定义可调参数。如需添加,请在模板 JSON 中添加 tuning 段。</p>
<a class="btn secondary" href="/assets/templates/{{.AssetTemplate.Name}}">返回</a>
</div>
{{end}}
{{end}}