153 lines
7.3 KiB
HTML
153 lines
7.3 KiB
HTML
{{define "alarms"}}
|
||
<div class="card">
|
||
<form method="get" action="/ui/alarms" style="display:flex;gap:8px;align-items:center;margin-bottom:12px;justify-content:space-between;flex-wrap:wrap">
|
||
<span style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
|
||
<input type="date" name="from" value="{{.SelectedFrom}}" style="width:130px;font-size:12px">
|
||
<span class="muted small">至</span>
|
||
<input type="date" name="to" value="{{.SelectedTo}}" style="width:130px;font-size:12px">
|
||
{{if .AlarmFilterDevices}}
|
||
<select name="device" onchange="this.form.submit()" style="font-size:11px;padding:2px 4px;width:130px;flex-shrink:0">
|
||
<option value="">全部设备</option>
|
||
{{range .AlarmFilterDevices}}
|
||
<option value="{{.}}" {{if eq . $.SelectedAlarmDevice}}selected{{end}}>{{shortID .}}</option>
|
||
{{end}}
|
||
</select>
|
||
{{end}}
|
||
{{if .AlarmFilterRuleTypes}}
|
||
<select name="rule_type" onchange="this.form.submit()" style="font-size:11px;padding:2px 4px;width:120px;flex-shrink:0">
|
||
<option value="">全部类型</option>
|
||
{{range .AlarmFilterRuleTypes}}
|
||
<option value="{{.}}" {{if eq . $.SelectedAlarmRuleType}}selected{{end}}>{{ruleLabel .}}</option>
|
||
{{end}}
|
||
</select>
|
||
{{end}}
|
||
<button class="btn" style="font-size:12px;padding:4px 12px">筛选</button>
|
||
<a href="/ui/alarms" class="btn ghost" style="font-size:11px">今天</a>
|
||
<a href="/ui/alarms?from={{.WeekStart}}&to={{.WeekEnd}}" class="btn ghost" style="font-size:11px">本周</a>
|
||
<a href="/ui/alarms?from={{.MonthStart}}&to={{.MonthEnd}}" class="btn ghost" style="font-size:11px">本月</a>
|
||
<a href="/ui/alarms?from=2020-01-01&to={{.SelectedTo}}" class="btn ghost" style="font-size:11px">全部</a>
|
||
</span>
|
||
<select name="per_page" onchange="this.form.submit()" style="font-size:11px;padding:2px 4px;width:90px;flex-shrink:0">
|
||
<option value="10" {{if eq .PerPage 10}}selected{{end}}>10条/页</option>
|
||
<option value="20" {{if eq .PerPage 20}}selected{{end}}>20条/页</option>
|
||
<option value="50" {{if eq .PerPage 50}}selected{{end}}>50条/页</option>
|
||
<option value="100" {{if eq .PerPage 100}}selected{{end}}>100条/页</option>
|
||
</select>
|
||
</form>
|
||
|
||
<div class="table-wrap">
|
||
{{if .AlarmRecords}}
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>时间</th>
|
||
<th>设备</th>
|
||
<th>通道</th>
|
||
<th>规则</th>
|
||
<th>目标</th>
|
||
<th>置信度</th>
|
||
<th>等级</th>
|
||
<th>状态</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{{range .AlarmRecords}}
|
||
<tr id="alarm-{{.ID}}">
|
||
<td class="mono small">{{.Timestamp}}</td>
|
||
<td>
|
||
<a href="/ui/devices/{{.DeviceID}}">{{shortID .DeviceID}}</a>
|
||
</td>
|
||
<td>{{.Channel}}</td>
|
||
<td>
|
||
<span class="pill warn">{{ruleLabel .RuleName}}</span>
|
||
</td>
|
||
<td>{{if .ObjectLabel}}{{.ObjectLabel}}{{else}}-{{end}}</td>
|
||
<td>{{if .Confidence}}{{printf "%.2f" .Confidence}}{{else}}-{{end}}</td>
|
||
<td>
|
||
<span class="pill {{severityClass .Severity}}">{{severityLabel .Severity}}</span>
|
||
</td>
|
||
<td>
|
||
<span class="pill {{statusClass .Status}}">{{statusLabel .Status}}</span>
|
||
</td>
|
||
<td>
|
||
<span style="display:flex;gap:4px;align-items:center;flex-wrap:wrap">
|
||
<button class="btn ghost" style="font-size:10px;padding:2px 6px;min-height:22px" data-alarm-action="acknowledge" data-alarm-id="{{.ID}}">确认</button>
|
||
<button class="btn ghost" style="font-size:10px;padding:2px 6px;min-height:22px" data-alarm-action="resolve" data-alarm-id="{{.ID}}">关闭</button>
|
||
<select style="font-size:10px;padding:1px 2px;width:70px;min-height:22px" data-alarm-action="severity" data-alarm-id="{{.ID}}" data-current="{{.Severity}}">
|
||
<option value="info" {{if eq .Severity "info"}}selected{{end}}>信息</option>
|
||
<option value="warning" {{if eq .Severity "warning"}}selected{{end}}>警告</option>
|
||
<option value="critical" {{if eq .Severity "critical"}}selected{{end}}>严重</option>
|
||
</select>
|
||
{{if .SnapshotURL}}
|
||
<a href="{{.SnapshotURL}}" target="_blank" class="btn ghost" style="font-size:10px;padding:2px 6px;min-height:22px">截图</a>
|
||
{{end}}
|
||
{{if .ClipURL}}
|
||
<a href="{{.ClipURL}}" target="_blank" class="btn ghost" style="font-size:10px;padding:2px 6px;min-height:22px">视频</a>
|
||
{{end}}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
{{end}}
|
||
</tbody>
|
||
</table>
|
||
{{if gt .TotalAlarmPages 1}}
|
||
<div style="margin-top:12px;display:flex;gap:4px;align-items:center">
|
||
<span class="muted small" style="margin-right:8px">{{.TotalAlarmCount}} 条,{{.TotalAlarmPages}} 页</span>
|
||
{{$from := $.SelectedFrom}}{{$to := $.SelectedTo}}{{$pp := $.PerPage}}{{$dev := $.SelectedAlarmDevice}}{{$rt := $.SelectedAlarmRuleType}}
|
||
{{if gt .CurrentPage 1}}
|
||
<a href="/ui/alarms?from={{$from}}&to={{$to}}&per_page={{$pp}}&device={{$dev}}&rule_type={{$rt}}" class="btn ghost" style="font-size:11px;padding:2px 6px">«</a>
|
||
<a href="/ui/alarms?from={{$from}}&to={{$to}}&per_page={{$pp}}&page={{sub .CurrentPage 1}}&device={{$dev}}&rule_type={{$rt}}" class="btn ghost" style="font-size:11px;padding:2px 6px">‹</a>
|
||
{{end}}
|
||
{{range .PageNumbers}}
|
||
{{if eq . -1}}
|
||
<span class="muted small" style="padding:2px 4px">…</span>
|
||
{{else}}
|
||
<a href="/ui/alarms?from={{$from}}&to={{$to}}&per_page={{$pp}}&page={{.}}&device={{$dev}}&rule_type={{$rt}}" class="btn {{if eq . $.CurrentPage}}primary{{else}}ghost{{end}}" style="font-size:11px;padding:2px 8px">{{.}}</a>
|
||
{{end}}
|
||
{{end}}
|
||
{{if lt .CurrentPage .TotalAlarmPages}}
|
||
<a href="/ui/alarms?from={{$from}}&to={{$to}}&per_page={{$pp}}&page={{add .CurrentPage 1}}&device={{$dev}}&rule_type={{$rt}}" class="btn ghost" style="font-size:11px;padding:2px 6px">›</a>
|
||
<a href="/ui/alarms?from={{$from}}&to={{$to}}&per_page={{$pp}}&page={{.TotalAlarmPages}}&device={{$dev}}&rule_type={{$rt}}" class="btn ghost" style="font-size:11px;padding:2px 6px">»</a>
|
||
{{end}}
|
||
</div>
|
||
{{end}}
|
||
{{else}}
|
||
<div class="empty-state">
|
||
<div class="empty-title">暂无告警记录</div>
|
||
<div class="muted">所选日期范围内没有告警记录。</div>
|
||
</div>
|
||
{{end}}
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
(function(){
|
||
function postAlarmAction(id, action, body) {
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open("POST", "/ui/alarms/" + id + "/" + action);
|
||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||
xhr.onload = function() {
|
||
if (xhr.status === 204) {
|
||
window.location.reload();
|
||
}
|
||
};
|
||
xhr.send(body || "");
|
||
}
|
||
document.querySelectorAll("[data-alarm-action]").forEach(function(el) {
|
||
var action = el.getAttribute("data-alarm-action");
|
||
var id = el.getAttribute("data-alarm-id");
|
||
if (action === "acknowledge" || action === "resolve") {
|
||
el.addEventListener("click", function() {
|
||
postAlarmAction(id, action);
|
||
});
|
||
} else if (action === "severity") {
|
||
el.addEventListener("change", function() {
|
||
postAlarmAction(id, "severity", "severity=" + encodeURIComponent(el.value));
|
||
});
|
||
}
|
||
});
|
||
})();
|
||
</script>
|
||
{{end}}
|