feat(web): slim the list filters and hide them when empty

At current scale the date-range pickers are dead weight (UX review C1/C2):

- Drop the From/To date inputs from the filter bar; keep the Channel field and
  the "Summarized only" toggle. (Filter still parses from/to for hand-built
  URLs and apply() compatibility — only the UI is removed.)
- Hide the filter bar entirely on a genuinely empty account (no rows AND no
  active filter) so the connect CTA stands alone; a filter that matches nothing
  still shows the bar so it can be cleared.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 13:59:44 +02:00
co-authored by Claude Opus 4.8
parent 40b703e02a
commit 980638d80a
4 changed files with 514 additions and 514 deletions
+16
View File
@@ -360,6 +360,22 @@ func TestListCollapsesOlderAndNoCaption(t *testing.T) {
require.NotContains(t, html, "No Caption Vid", "caption-less video is collapsed, not a card")
}
// TestListHidesFilterBarWhenEmpty: a genuinely empty list shows no filter bar
// (the connect CTA stands alone), but a filter that matches nothing still shows
// the bar so it can be cleared (UX review C1).
func TestListHidesFilterBarWhenEmpty(t *testing.T) {
app := newApp(t)
resetDB(t, rawPool(t))
rec := do(t, app, httptest.NewRequest(http.MethodGet, "/", nil))
require.Equal(t, http.StatusOK, rec.Code)
require.NotContains(t, body(t, rec), `class="filters"`, "no filter bar on an empty account")
rec = do(t, app, httptest.NewRequest(http.MethodGet, "/?channel=nope", nil))
require.Equal(t, http.StatusOK, rec.Code)
require.Contains(t, body(t, rec), `class="filters"`, "filtered-to-empty keeps the bar so it can be cleared")
}
func TestRequestSummarizeQueuesAndRendersCard(t *testing.T) {
ctx := context.Background()
app := newApp(t)
+8
View File
@@ -475,6 +475,14 @@ type Filter struct {
OnlySummarized bool // show only videos that have a summary
}
// active reports whether any filter constraint is set. Drives whether the filter
// bar is shown at all: on a genuinely empty account (no rows AND no active
// filter) the bar is hidden so the connect CTA stands alone (UX review C1); a
// filter that happens to match nothing still shows the bar so it can be cleared.
func (f Filter) active() bool {
return f.Channel != "" || f.From != "" || f.To != "" || f.OnlySummarized
}
// matches reports whether a row satisfies the filter. Channel is an exact match;
// From/To bound PublishedAt inclusively. Unparseable or empty bounds are ignored
// (no constraint) — Stage-0 filtering is in-memory over the listed rows, not a
+3 -3
View File
@@ -107,7 +107,9 @@ templ flashBanner(code string) {
templ ListPage(b listBuckets, f Filter, stats PipelineStats, flash string, hasConnected bool) {
@Layout("Tapir — Summaries") {
@flashBanner(flash)
@filterForm(f)
if !b.empty() || f.active() {
@filterForm(f)
}
if stats.RateLimited > 0 || stats.Pending > 0 || stats.NoText > 0 {
@pipelineBar(stats)
}
@@ -152,8 +154,6 @@ templ filterForm(f Filter) {
hx-indicator="#filter-indicator"
>
<label>Channel <input type="text" name="channel" value={ f.Channel } placeholder="any"/></label>
<label>From <input type="date" name="from" value={ f.From }/></label>
<label>To <input type="date" name="to" value={ f.To }/></label>
<label class="filter-check">
<input type="checkbox" name="summarized" value="1" if f.OnlySummarized { checked }/>
Summarized only
File diff suppressed because it is too large Load Diff