3588AdminBackend/internal/web/ui/templates/config_preview.html

150 lines
7.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{define "config_preview"}}
{{template "device_nav" .}}
<div class="card">
<div class="section-title">
<div>
<h2>配置预览</h2>
<div class="muted small">基于模板、Profile 和 Overlay 生成完整配置预览;此页面不会下发到设备。</div>
</div>
<a class="btn ghost" href="/ui/devices/{{.Device.DeviceID}}">返回节点详情</a>
</div>
</div>
<div class="card">
<h2>生成配置预览</h2>
{{if .ConfigSources.Root}}<div class="muted small">Media 仓库:<span class="mono">{{.ConfigSources.Root}}</span></div>{{end}}
<div class="muted small" style="margin-top:8px">
<span class="mono">config_id</span> 是配置名,默认会带上 <span class="mono">device_id</span>(当前设备:<span class="mono">{{.Device.DeviceID}}</span><span class="mono">config_version</span> 表示本次生成版本;<span class="mono">SHA256</span> 是最终文件内容指纹。
</div>
<form method="post" action="/ui/devices/{{.Device.DeviceID}}/config-preview" style="margin-top:12px">
<div class="row">
<div>
<div class="muted small">模板</div>
<select name="template">
{{range .ConfigSources.Templates}}
<option value="{{.Name}}" {{if eq .Name $.SelectedTemplate}}selected{{end}}>{{.Name}}</option>
{{end}}
</select>
</div>
<div>
<div class="muted small">Profile</div>
<select name="profile">
{{range .ConfigSources.Profiles}}
<option value="{{.Name}}" {{if eq .Name $.SelectedProfile}}selected{{end}}>{{.Name}}</option>
{{end}}
</select>
</div>
<div>
<div class="muted small">config_id</div>
<input name="config_id" value="{{.SelectedConfigID}}" />
</div>
<div>
<div class="muted small">config_version</div>
<input name="config_version" value="{{.SelectedVersion}}" placeholder="留空自动生成" />
</div>
</div>
<div style="margin-top:12px">
<div class="muted small">Overlay</div>
<div class="actions" style="margin-top:6px">
{{range .ConfigSources.Overlays}}
<label class="btn ghost">
<input type="checkbox" name="overlay" value="{{.Name}}" {{if hasString $.SelectedOverlays .Name}}checked{{end}} />
{{.Name}}
</label>
{{end}}
</div>
</div>
<div class="actions" style="margin-top:12px">
<button type="submit">生成预览</button>
<button type="button" disabled>上传为候选配置</button>
{{if and .ConfigStatus .ConfigStatus.Candidate .ConfigStatus.Candidate.Exists}}
<button type="submit" formaction="/ui/devices/{{.Device.DeviceID}}/config-candidate/apply">应用候选配置</button>
{{else}}
<button type="button" disabled>应用候选配置</button>
{{end}}
<a class="btn ghost" href="/ui/devices/{{.Device.DeviceID}}">查看当前运行配置</a>
</div>
</form>
</div>
{{if .ConfigPreview}}
<div class="card">
<h2>预览摘要</h2>
<div class="row" style="margin-top:10px">
<div><div class="muted small">配置 ID</div><div class="mono">{{index .ConfigPreview.Metadata "config_id"}}</div></div>
<div><div class="muted small">版本</div><div class="mono">{{index .ConfigPreview.Metadata "config_version"}}</div></div>
<div><div class="muted small">模板</div><div class="mono">{{index .ConfigPreview.Metadata "template"}}</div></div>
<div><div class="muted small">Profile</div><div class="mono">{{index .ConfigPreview.Metadata "profile"}}</div></div>
<div><div class="muted small">大小</div><div class="mono">{{.ConfigPreview.Size}} bytes</div></div>
</div>
<div style="margin-top:10px">
<div class="muted small">Overlay</div>
<div class="mono">{{if index .ConfigPreview.Metadata "overlays"}}{{range $i, $name := index .ConfigPreview.Metadata "overlays"}}{{if $i}}, {{end}}{{$name}}{{end}}{{else}}-{{end}}</div>
</div>
<div style="margin-top:10px">
<div class="muted small">SHA256</div>
<div class="mono small">{{.ConfigPreview.Sha256}}</div>
</div>
</div>
<div class="card">
<h2>完整 JSON</h2>
<form method="post" action="/ui/devices/{{.Device.DeviceID}}/config-candidate" class="actions" style="margin-bottom:10px">
<input type="hidden" name="json" value="{{.ConfigPreview.JSON}}" />
<button type="submit">上传为候选配置</button>
<button type="submit" formaction="/ui/devices/{{.Device.DeviceID}}/config-candidate/apply">应用候选配置</button>
<a class="btn ghost" href="/ui/devices/{{.Device.DeviceID}}">查看当前运行配置</a>
</form>
{{if .RawText}}
<details>
<summary class="muted small">展开完整 JSON</summary>
<pre>{{.ConfigPreview.JSON}}</pre>
</details>
{{else}}
<details open>
<summary class="muted small">展开完整 JSON</summary>
<pre>{{.ConfigPreview.JSON}}</pre>
</details>
{{end}}
</div>
{{end}}
{{if and (eq .ResultTitle "应用候选配置结果") .ConfigStatus}}
<div class="card">
<h2>应用结果摘要</h2>
<div class="row" style="margin-top:10px">
<div>
<div class="muted small">当前运行</div>
<div class="mono">{{if .ConfigStatus.Metadata.ConfigID}}{{.ConfigStatus.Metadata.ConfigID}} / {{if .ConfigStatus.Metadata.ConfigVersion}}{{.ConfigStatus.Metadata.ConfigVersion}}{{else}}未标记{{end}}{{else}}未标记{{end}}</div>
<div class="muted small mono" style="margin-top:6px">{{if .ConfigStatus.Metadata.Overlays}}{{range $i, $name := .ConfigStatus.Metadata.Overlays}}{{if $i}}, {{end}}{{$name}}{{end}}{{else}}-{{end}}</div>
<div class="muted small mono" style="margin-top:6px">sha: {{shortHash .ConfigStatus.Sha256}}</div>
</div>
<div>
<div class="muted small">上一份配置</div>
<div class="mono">{{if and .ConfigStatus.LastGood .ConfigStatus.LastGood.Exists .ConfigStatus.LastGood.Metadata.ConfigID}}{{.ConfigStatus.LastGood.Metadata.ConfigID}} / {{if .ConfigStatus.LastGood.Metadata.ConfigVersion}}{{.ConfigStatus.LastGood.Metadata.ConfigVersion}}{{else}}未标记{{end}}{{else}}-{{end}}</div>
<div class="muted small mono" style="margin-top:6px">{{if and .ConfigStatus.LastGood .ConfigStatus.LastGood.Metadata.Overlays}}{{range $i, $name := .ConfigStatus.LastGood.Metadata.Overlays}}{{if $i}}, {{end}}{{$name}}{{end}}{{else}}-{{end}}</div>
<div class="muted small mono" style="margin-top:6px">sha: {{if .ConfigStatus.LastGood}}{{shortHash .ConfigStatus.LastGood.Sha256}}{{end}}</div>
</div>
<div>
<div class="muted small">candidate</div>
<div>{{if and .ConfigStatus.Candidate .ConfigStatus.Candidate.Exists}}<span class="pill">仍存在</span>{{else}}<span class="pill ok">已清空</span>{{end}}</div>
</div>
<div>
<div class="muted small">media-server</div>
<div>{{if .ConfigStatus.MediaServer.Running}}<span class="pill ok">运行中</span>{{else}}<span class="pill bad">未运行</span>{{end}}</div>
</div>
</div>
{{if and .ConfigStatus.LastGood .ConfigStatus.Sha256 .ConfigStatus.LastGood.Sha256 (eq .ConfigStatus.Metadata.ConfigID .ConfigStatus.LastGood.Metadata.ConfigID) (eq .ConfigStatus.Metadata.ConfigVersion .ConfigStatus.LastGood.Metadata.ConfigVersion) (ne .ConfigStatus.Sha256 .ConfigStatus.LastGood.Sha256)}}
<div class="muted small" style="margin-top:10px">当前运行与上一份配置回滚点的 <span class="mono">config_id/config_version</span> 相同,但文件内容不同,请以 <span class="mono">overlay</span><span class="mono">sha</span> 为准。</div>
{{end}}
</div>
{{end}}
{{if .RawText}}
<div class="card">
<h2>{{if .ResultTitle}}{{.ResultTitle}}{{else}}执行结果{{end}}</h2>
<pre>{{.RawText}}</pre>
</div>
{{end}}
{{end}}