Files
backup-master/internal/server/templates/clients.html
T
mrleo1nidandClaude Opus 5.5 83832fc734
CI / test (push) Successful in 1m19s
Release / release (push) Successful in 1m18s
Веб-морда: поиск, фильтры, сортировка и пагинация клиентов; раскладка настроек
- список клиентов: поиск по домену и названию, фильтр по статусу (чипы
  со счётчиками), сортировка по любой колонке, пагинация 10/25/50/100;
  состояние в URL — отфильтрованный вид можно сохранить ссылкой
- размеры последних бэкапов одним запросом вместо запроса на клиента
- шапка выровнена по колонке контента; настройки на всю ширину:
  ntfy и Telegram двумя карточками, на узком экране — друг под другом

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 22:42:32 +03:00

66 lines
3.5 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 "title"}}Клиенты — backup-master{{end}}
{{define "content"}}
{{$v := .V}}{{$q := .V.Query}}
<div class="head">
<h1>Клиенты <span class="muted small">{{$v.Total}}</span></h1>
<a class="button primary" href="/clients/new">Добавить клиента</a>
</div>
{{if $v.Total}}
<form method="get" action="/" class="toolbar">
<input type="search" name="q" value="{{$q.Q}}" placeholder="Поиск по домену или названию" autofocus>
{{if $q.Status}}<input type="hidden" name="status" value="{{$q.Status}}">{{end}}
{{if ne $q.Sort "domain"}}<input type="hidden" name="sort" value="{{$q.Sort}}">{{end}}
{{with $q.DirParam}}<input type="hidden" name="dir" value="{{.}}">{{end}}
<select name="per" onchange="this.form.submit()" title="Строк на странице">
{{range $v.PerOpts}}<option value="{{.}}" {{if eq . $q.Per}}selected{{end}}>по {{.}}</option>{{end}}
</select>
<button>Найти</button>
{{if or $q.Q $q.Status}}<a class="button" href="/">Сбросить</a>{{end}}
</form>
<div class="chips toolbar">
{{range $v.Chips}}<a class="chip {{if .Active}}active{{end}}" href="{{.URL}}">{{.Title}} <span class="count">{{.Count}}</span></a>{{end}}
</div>
{{if $v.Rows}}
<div class="table-wrap">
<table>
<thead><tr>
<th><a href="{{$q.SortURL "domain"}}" {{if eq $q.Sort "domain"}}class="sorted"{{end}}>Домен {{$q.SortMark "domain"}}</a></th>
<th><a href="{{$q.SortURL "name"}}" {{if eq $q.Sort "name"}}class="sorted"{{end}}>Название {{$q.SortMark "name"}}</a></th>
<th><a href="{{$q.SortURL "status"}}" {{if eq $q.Sort "status"}}class="sorted"{{end}}>Статус {{$q.SortMark "status"}}</a></th>
<th><a href="{{$q.SortURL "last_backup"}}" {{if eq $q.Sort "last_backup"}}class="sorted"{{end}}>Последний бэкап {{$q.SortMark "last_backup"}}</a></th>
<th class="num"><a href="{{$q.SortURL "size"}}" {{if eq $q.Sort "size"}}class="sorted"{{end}}>Размер {{$q.SortMark "size"}}</a></th>
<th><a href="{{$q.SortURL "last_seen"}}" {{if eq $q.Sort "last_seen"}}class="sorted"{{end}}>Агент на связи {{$q.SortMark "last_seen"}}</a></th>
</tr></thead>
<tbody>
{{range $v.Rows}}
<tr>
<td><a href="/clients/{{.ID}}">{{.Domain}}</a></td>
<td>{{if ne .Name .Domain}}{{.Name}}{{end}}</td>
<td><span class="badge {{.StatusClass}}">{{.StatusText}}</span>{{if and (eq .StatusClass "fail") .LastError}} <span class="muted small" title="{{.LastError}}">{{.LastError}}</span>{{end}}</td>
<td title="{{ts .LastBackupAt}}">{{ago .LastBackupAt}}</td>
<td class="num">{{if .LastSize}}{{bytes .LastSize}}{{end}}</td>
<td title="{{ts .LastSeenAt}}">{{ago .LastSeenAt}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
<div class="pager">
<span>{{$v.From}}–{{$v.To}} из {{$v.Found}}{{if ne $v.Found $v.Total}} (всего {{$v.Total}}){{end}}</span>
{{if $v.Pages}}
<div class="pages">
{{if $v.Prev}}<a href="{{$v.Prev}}">←</a>{{end}}
{{range $v.Pages}}{{if .Gap}}<span class="gap">…</span>{{else if .Current}}<span class="current">{{.N}}</span>{{else}}<a href="{{.URL}}">{{.N}}</a>{{end}}{{end}}
{{if $v.Next}}<a href="{{$v.Next}}">→</a>{{end}}
</div>
{{end}}
</div>
{{else}}
<p class="empty">Ничего не найдено. <a href="/">Сбросить фильтры</a></p>
{{end}}
{{else}}
<p class="empty">Клиентов пока нет. Добавьте первый — получите команду установки агента.</p>
{{end}}
{{end}}