{{define "overview_stats"}}
{{.Status.TotalIPs}}всего IP
{{.Status.TotalValidators}}валидаторов
{{range $state, $count := .Status.IPsByState}}
{{$count}}{{$state}}
{{end}}
{{if .Progress.Total}}

Готово {{.Progress.Done}} из {{.Progress.Total}} ({{.Progress.Percent}}%) · в работе {{.Progress.Active}} · в очереди {{.Progress.Queued}}{{if .Progress.ETA}} · осталось ≈ {{.Progress.ETA}}{{end}}

{{end}} {{with .Status.ResultsByOverall}}{{if or (index . "pass") (index . "partial") (index . "fail") (index . "cancelled")}}

Итоги проверок: pass {{index . "pass"}} · partial {{index . "partial"}} · fail {{index . "fail"}} · cancelled {{index . "cancelled"}}

{{end}}{{end}} {{with .Scan}}

Сканирование: {{.StateLabel}}{{if .DryRun}} (пробное){{end}} · прочитано страниц {{.Pages}}, найдено адресов {{.Discovered}}, свободных {{.Free}}{{if .Handled}}, обработано {{.Handled}}{{end}} · подробнее

{{end}} {{with .AutoCycle}}{{if .Enabled}}

Автоцикл активен · {{.PhaseLabel}} · следующий запуск: {{fmtTime .NextRunAt}}

{{end}}{{end}} {{end}} {{/* Out-of-band counterpart of overview_stats, appended to every /overview/fragment response alongside overview_tables (the actual hx-target) — same OOB idiom as templates/layout.html's error_banner. Needed because overview_stats lives outside the polled #overview-tables div (see overview.html) so the DOM order can be stats -> filter form -> tables, yet the stat counts still refresh on every poll tick. */}} {{define "overview_stats_oob"}}
{{template "overview_stats" .}}
{{end}} {{define "overview_tables"}}

В работе

{{if .ActiveItems}}
{{range .ActiveItems}} {{$b := ipBadge .State .OverallResult .FIPAssociatedAt 0}} {{end}}
АдресСостояниеВалидаторПопыткаНазначено
{{.IPAddress}} {{$b.Label}} {{deref .OwnerValidatorID}} {{.AttemptNumber}} {{fmtTime .AssignedAt}}
{{if gt .ActiveTotal (len .ActiveItems)}}

Показано {{len .ActiveItems}} из {{.ActiveTotal}} · все в работе

{{end}} {{else}} {{if or .Query .StatusFilter}}

Ничего не найдено по текущему фильтру.

{{else}}

Сейчас нет адресов в обработке.

{{end}} {{end}} {{if not .StatusFilter}}

В очереди: {{.QueuedTotal}} · открыть весь список

{{if .QueuedItems}}
{{range .QueuedItems}} {{$b := ipBadge .State .OverallResult .FIPAssociatedAt 0}} {{end}}
Ближайшие в очередиСостояние
{{.IPAddress}} {{$b.Label}}
{{if gt .QueuedTotal (len .QueuedItems)}}

Показаны ближайшие {{len .QueuedItems}} из {{.QueuedTotal}}.

{{end}} {{end}} {{end}}

Последние {{.LastN}} завершённых

pass {{index .Breakdown "pass"}} partial {{index .Breakdown "partial"}} fail {{index .Breakdown "fail"}} cancelled {{index .Breakdown "cancelled"}}
{{if .LastCompleted}}
{{range .LastCompleted}} {{$b := ipBadge .State .OverallResult .FIPAssociatedAt 0}} {{end}}
АдресИтогЗавершено
{{.IPAddress}} {{$b.Label}} {{fmtTime .AggregatedAt}}
{{else}} {{if or .Query .StatusFilter}}

Ничего не найдено по текущему фильтру.

{{else}}

Пока ничего не завершено.

{{end}} {{end}} {{end}}