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:
@@ -360,6 +360,22 @@ func TestListCollapsesOlderAndNoCaption(t *testing.T) {
|
|||||||
require.NotContains(t, html, "No Caption Vid", "caption-less video is collapsed, not a card")
|
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) {
|
func TestRequestSummarizeQueuesAndRendersCard(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
app := newApp(t)
|
app := newApp(t)
|
||||||
|
|||||||
@@ -475,6 +475,14 @@ type Filter struct {
|
|||||||
OnlySummarized bool // show only videos that have a summary
|
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;
|
// matches reports whether a row satisfies the filter. Channel is an exact match;
|
||||||
// From/To bound PublishedAt inclusively. Unparseable or empty bounds are ignored
|
// 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
|
// (no constraint) — Stage-0 filtering is in-memory over the listed rows, not a
|
||||||
|
|||||||
@@ -107,7 +107,9 @@ templ flashBanner(code string) {
|
|||||||
templ ListPage(b listBuckets, f Filter, stats PipelineStats, flash string, hasConnected bool) {
|
templ ListPage(b listBuckets, f Filter, stats PipelineStats, flash string, hasConnected bool) {
|
||||||
@Layout("Tapir — Summaries") {
|
@Layout("Tapir — Summaries") {
|
||||||
@flashBanner(flash)
|
@flashBanner(flash)
|
||||||
|
if !b.empty() || f.active() {
|
||||||
@filterForm(f)
|
@filterForm(f)
|
||||||
|
}
|
||||||
if stats.RateLimited > 0 || stats.Pending > 0 || stats.NoText > 0 {
|
if stats.RateLimited > 0 || stats.Pending > 0 || stats.NoText > 0 {
|
||||||
@pipelineBar(stats)
|
@pipelineBar(stats)
|
||||||
}
|
}
|
||||||
@@ -152,8 +154,6 @@ templ filterForm(f Filter) {
|
|||||||
hx-indicator="#filter-indicator"
|
hx-indicator="#filter-indicator"
|
||||||
>
|
>
|
||||||
<label>Channel <input type="text" name="channel" value={ f.Channel } placeholder="any"/></label>
|
<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">
|
<label class="filter-check">
|
||||||
<input type="checkbox" name="summarized" value="1" if f.OnlySummarized { checked }/>
|
<input type="checkbox" name="summarized" value="1" if f.OnlySummarized { checked }/>
|
||||||
Summarized only
|
Summarized only
|
||||||
|
|||||||
+493
-517
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user