You've already forked caddy-opnsense-blocker
Refine requests log filter controls
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
type App interface {
|
||||
GetOverview(ctx context.Context, since time.Time, limit int, options model.OverviewOptions) (model.Overview, error)
|
||||
ListEvents(ctx context.Context, since time.Time, limit int, options model.EventListOptions) ([]model.Event, error)
|
||||
ListSourceNames() []string
|
||||
ListIPs(ctx context.Context, limit int, state string) ([]model.IPState, error)
|
||||
ListRecentIPs(ctx context.Context, since time.Time, limit int) ([]model.RecentIPRow, error)
|
||||
GetIPDetails(ctx context.Context, ip string) (model.IPDetails, error)
|
||||
@@ -36,8 +37,9 @@ type handler struct {
|
||||
}
|
||||
|
||||
type pageData struct {
|
||||
Title string
|
||||
IP string
|
||||
Title string
|
||||
IP string
|
||||
Sources []string
|
||||
}
|
||||
|
||||
type actionPayload struct {
|
||||
@@ -92,7 +94,7 @@ func (h *handler) handleQueryLogPage(w http.ResponseWriter, r *http.Request) {
|
||||
methodNotAllowed(w)
|
||||
return
|
||||
}
|
||||
renderTemplate(w, h.queryLogPage, pageData{Title: "Requests Log"})
|
||||
renderTemplate(w, h.queryLogPage, pageData{Title: "Requests Log", Sources: h.app.ListSourceNames()})
|
||||
}
|
||||
|
||||
func (h *handler) handleIPPage(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -1020,25 +1022,52 @@ const queryLogHTML = `<!doctype html>
|
||||
<form class="filters-grid" id="controls-form" onsubmit="applyFilters(event)">
|
||||
<div class="field">
|
||||
<label for="source-filter">Source</label>
|
||||
<input id="source-filter" type="text" placeholder="gitea">
|
||||
<select id="source-filter">
|
||||
<option value="">Any source</option>
|
||||
{{ range .Sources }}<option value="{{ . }}">{{ . }}</option>{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="method-filter">Method</label>
|
||||
<input id="method-filter" type="text" list="method-options" placeholder="GET">
|
||||
<datalist id="method-options">
|
||||
<option value="GET"></option>
|
||||
<option value="POST"></option>
|
||||
<option value="HEAD"></option>
|
||||
<option value="PUT"></option>
|
||||
<option value="DELETE"></option>
|
||||
<option value="PATCH"></option>
|
||||
<option value="OPTIONS"></option>
|
||||
<option value="OTHER"></option>
|
||||
</datalist>
|
||||
<select id="method-filter">
|
||||
<option value="">Any method</option>
|
||||
<option value="GET">GET</option>
|
||||
<option value="POST">POST</option>
|
||||
<option value="HEAD">HEAD</option>
|
||||
<option value="PUT">PUT</option>
|
||||
<option value="DELETE">DELETE</option>
|
||||
<option value="PATCH">PATCH</option>
|
||||
<option value="OPTIONS">OPTIONS</option>
|
||||
<option value="OTHER">OTHER</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="status-filter">HTTP status</label>
|
||||
<input id="status-filter" type="text" placeholder="404 or 4xx">
|
||||
<select id="status-filter">
|
||||
<option value="">Any status</option>
|
||||
<optgroup label="Status classes">
|
||||
<option value="2xx">2xx</option>
|
||||
<option value="3xx">3xx</option>
|
||||
<option value="4xx">4xx</option>
|
||||
<option value="5xx">5xx</option>
|
||||
</optgroup>
|
||||
<optgroup label="Common client errors">
|
||||
<option value="400">400</option>
|
||||
<option value="401">401</option>
|
||||
<option value="403">403</option>
|
||||
<option value="404">404</option>
|
||||
<option value="405">405</option>
|
||||
<option value="408">408</option>
|
||||
<option value="410">410</option>
|
||||
<option value="429">429</option>
|
||||
</optgroup>
|
||||
<optgroup label="Common server errors">
|
||||
<option value="500">500</option>
|
||||
<option value="502">502</option>
|
||||
<option value="503">503</option>
|
||||
<option value="504">504</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="state-filter">State</label>
|
||||
|
||||
@@ -169,6 +169,15 @@ func TestHandlerServesOverviewAndManualActions(t *testing.T) {
|
||||
if !strings.Contains(queryLogBody, "Filters, sorting, and pagination") {
|
||||
t.Fatalf("requests log page should expose the collapsible controls panel")
|
||||
}
|
||||
if !strings.Contains(queryLogBody, `<select id="source-filter">`) || !strings.Contains(queryLogBody, `<option value="main">main</option>`) {
|
||||
t.Fatalf("requests log page should expose a source dropdown with configured sources")
|
||||
}
|
||||
if !strings.Contains(queryLogBody, `<select id="method-filter">`) || !strings.Contains(queryLogBody, `<option value="POST">POST</option>`) {
|
||||
t.Fatalf("requests log page should expose a method dropdown")
|
||||
}
|
||||
if !strings.Contains(queryLogBody, `<select id="status-filter">`) || !strings.Contains(queryLogBody, `<option value="4xx">4xx</option>`) {
|
||||
t.Fatalf("requests log page should expose a structured HTTP status dropdown")
|
||||
}
|
||||
if !strings.Contains(queryLogBody, "Rows per page") {
|
||||
t.Fatalf("requests log page should expose pagination settings")
|
||||
}
|
||||
@@ -224,6 +233,10 @@ type stubApp struct {
|
||||
lastEventOptions model.EventListOptions
|
||||
}
|
||||
|
||||
func (s *stubApp) ListSourceNames() []string {
|
||||
return []string{"gitea", "main"}
|
||||
}
|
||||
|
||||
func (s *stubApp) GetOverview(_ context.Context, _ time.Time, _ int, options model.OverviewOptions) (model.Overview, error) {
|
||||
s.lastOverviewOptions = options
|
||||
now := time.Now().UTC()
|
||||
|
||||
Reference in New Issue
Block a user