All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m40s
Enhance the admin panel by introducing visual overview charts for upload and storage trends, along with status bars for system metrics. Additionally, implement pagination for the admin logs view, allowing users to navigate through log entries with configurable page sizes. Corresponding CSS styles have been added for the new charts, metrics grid, and pagination controls.
122 lines
6.2 KiB
HTML
122 lines
6.2 KiB
HTML
{{define "admin_logs.html"}}{{template "base" .}}{{end}}
|
||
|
||
{{define "content"}}
|
||
<section class="app-shell admin-shell" aria-labelledby="admin-logs-title">
|
||
<aside class="app-sidebar">
|
||
<nav class="sidebar-nav">
|
||
<a class="sidebar-link" href="/admin">{{template "icon-dashboard" .}}<span>Overview</span></a>
|
||
<a class="sidebar-link" href="/admin/files">{{template "icon-folder" .}}<span>Files</span></a>
|
||
<a class="sidebar-link" href="/admin/users">{{template "icon-user-circle" .}}<span>Users</span></a>
|
||
<a class="sidebar-link" href="/admin/settings">{{template "icon-settings" .}}<span>Settings</span></a>
|
||
<a class="sidebar-link" href="/admin/storage">{{template "icon-database" .}}<span>Storage</span></a>
|
||
<a class="sidebar-link is-active" href="/admin/logs">{{template "icon-database" .}}<span>Logs</span></a>
|
||
<a class="sidebar-link" href="/admin/bans">{{template "icon-settings" .}}<span>Bans</span></a>
|
||
</nav>
|
||
<hr class="sidebar-sep">
|
||
<nav class="sidebar-nav"><a class="sidebar-link" href="/app">{{template "icon-home-simple" .}}<span>My Files</span></a></nav>
|
||
<hr class="sidebar-sep">
|
||
<form class="sidebar-logout" action="/admin/logout" method="post">
|
||
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
||
<button class="button button-outline" type="submit">{{template "icon-log-out" .}}<span>Sign out</span></button>
|
||
</form>
|
||
</aside>
|
||
|
||
<div class="app-main">
|
||
<div class="admin-header">
|
||
<div>
|
||
<p class="kicker">Operator console</p>
|
||
<h1 id="admin-logs-title">{{.Data.PageTitle}}</h1>
|
||
<p class="muted-copy">Browse JSON log lines from the local log files.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<form class="logs-filter-card" method="get" action="/admin/logs">
|
||
<label><span>Date</span>
|
||
<select name="date">
|
||
<option value="all" {{if eq .Data.Logs.Date "all"}}selected{{end}}>All dates</option>
|
||
{{range .Data.Logs.Dates}}<option value="{{.}}" {{if eq $.Data.Logs.Date .}}selected{{end}}>{{.}}</option>{{end}}
|
||
</select>
|
||
</label>
|
||
<label><span>Severity</span>
|
||
<select name="severity">
|
||
<option value="" {{if eq .Data.Logs.Severity ""}}selected{{end}}>All</option>
|
||
<option value="dev" {{if eq .Data.Logs.Severity "dev"}}selected{{end}}>dev</option>
|
||
<option value="user_activity" {{if eq .Data.Logs.Severity "user_activity"}}selected{{end}}>user_activity</option>
|
||
<option value="warn" {{if eq .Data.Logs.Severity "warn"}}selected{{end}}>warn</option>
|
||
<option value="error" {{if eq .Data.Logs.Severity "error"}}selected{{end}}>error</option>
|
||
</select>
|
||
</label>
|
||
<label><span>Source</span><input name="source" value="{{.Data.Logs.Source}}" placeholder="auth, admin, upload"></label>
|
||
<label><span>Search</span><input name="q" value="{{.Data.Logs.Query}}" placeholder="message, IP, path, user id"></label>
|
||
<label><span>Sort</span>
|
||
<select name="sort">
|
||
<option value="desc" {{if eq .Data.Logs.Sort "desc"}}selected{{end}}>Newest first</option>
|
||
<option value="asc" {{if eq .Data.Logs.Sort "asc"}}selected{{end}}>Oldest first</option>
|
||
</select>
|
||
</label>
|
||
<input type="hidden" name="per" value="{{.Data.Logs.PerPage}}">
|
||
<button class="button button-primary" type="submit">Filter</button>
|
||
</form>
|
||
|
||
<div class="card admin-table-card">
|
||
<div class="card-content">
|
||
<div class="table-header">
|
||
<div>
|
||
<h2>Log entries</h2>
|
||
<p>{{.Data.Logs.Total}} entries match these filters.</p>
|
||
</div>
|
||
</div>
|
||
<div class="admin-table-wrap">
|
||
<table class="admin-table logs-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Time</th>
|
||
<th>Severity</th>
|
||
<th>Source</th>
|
||
<th>Code</th>
|
||
<th>Message</th>
|
||
<th>Actor/IP</th>
|
||
<th>Route</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{{range .Data.Logs.Entries}}
|
||
<tr>
|
||
<td><span class="log-time">{{.Date}} {{.Time}}</span></td>
|
||
<td><span class="badge">{{.Severity}}</span></td>
|
||
<td>{{.Source}}</td>
|
||
<td>{{.Code}}</td>
|
||
<td>
|
||
<strong>{{.Message}}</strong>
|
||
{{if .Details}}<details><summary>Details</summary><code>{{.Details}}</code></details>{{end}}
|
||
</td>
|
||
<td>{{if .UserID}}<code>{{.UserID}}</code>{{end}}{{if .IP}}<br><span>{{.IP}}</span>{{end}}</td>
|
||
<td>{{if .Method}}{{.Method}}{{end}} {{if .Path}}<code>{{.Path}}</code>{{end}}{{if .Status}}<br><span>Status {{.Status}}</span>{{end}}</td>
|
||
</tr>
|
||
{{else}}
|
||
<tr><td colspan="7">No log entries match those filters.</td></tr>
|
||
{{end}}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="pagination-bar">
|
||
<nav class="pagination" aria-label="Pagination">
|
||
{{if .Data.Logs.HasPrev}}<a class="button button-outline button-sm" href="{{.Data.Logs.PrevHref}}">← Prev</a>{{else}}<span class="button button-outline button-sm is-disabled" aria-disabled="true">← Prev</span>{{end}}
|
||
{{range .Data.Logs.PageLinks}}<a class="button button-sm {{if .Active}}is-active{{else}}button-outline{{end}}" href="{{.Href}}">{{.Page}}</a>{{end}}
|
||
{{if .Data.Logs.HasNext}}<a class="button button-outline button-sm" href="{{.Data.Logs.NextHref}}">Next →</a>{{else}}<span class="button button-outline button-sm is-disabled" aria-disabled="true">Next →</span>{{end}}
|
||
</nav>
|
||
<label class="per-page-control">
|
||
<span>Per page</span>
|
||
<select data-per-page="logs" aria-label="Items per page">
|
||
{{range .Data.Logs.PerPageOptions}}<option value="{{.}}" {{if eq . $.Data.Logs.PerPage}}selected{{end}}>{{.}}</option>{{end}}
|
||
</select>
|
||
</label>
|
||
</div>
|
||
<p class="pagination-summary">Showing {{.Data.Logs.RangeFrom}}–{{.Data.Logs.RangeTo}} of {{.Data.Logs.Total}} · Page {{.Data.Logs.Page}} of {{.Data.Logs.TotalPages}}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
{{end}}
|