Skip to content

feat(web): show applied-filter count badge on search filter toggle#684

Merged
memtomem merged 2 commits intomainfrom
feat/search-filter-count-badge
May 2, 2026
Merged

feat(web): show applied-filter count badge on search filter toggle#684
memtomem merged 2 commits intomainfrom
feat/search-filter-count-badge

Conversation

@memtomem
Copy link
Copy Markdown
Owner

@memtomem memtomem commented May 2, 2026

Summary

  • The ▾ Filters toggle only flipped to btn-active when the filter
    row was open; how many filters were actually applied was visible only
    via the chip row, which itself only renders alongside search results.
    Open the filters, set a tag and a namespace, collapse the row, and
    the toggle looked the same as if nothing was set.
  • Add a small accent-coloured count badge inside the toggle that
    mirrors the chip set in _renderActiveFilters (namespace, tag, chunk
    type, score threshold).
  • Cache-busts: style.css?v=73 → v=74, app.js?v=89 → v=90.

Why

UX walk-through flagged this as the smallest "the toggle is lying to
me" moment in the search bar. Counting the applied filters in one
place keeps the chip row and the toggle from disagreeing.

Update edges

The badge updates from four spots so the form, the chip row, URL
restore, and language toggle all stay in sync:

  • input on #tag-filter / change on #ns-filter /
    change on #chunk-type-filter / input on #score-threshold
    → tracks the form before the user even runs a search.
  • _renderActiveFilters at search time → chip-✕ removals keep the
    count honest.
  • _loadSearchFromURL for the URL-restored case (e.g. ?type=…).
  • langchange event → aria-label localizes alongside the rest of
    the UI.

i18n

Adds search.filter_count_aria_one / _other to en.json and
ko.json, following the existing CLDR _one/_other pattern (see
PR #608 and index.upload_usage_count_*).

Test plan

  • node --check packages/memtomem/src/memtomem/web/static/app.js
  • python -m json.tool on both locale files (parses)
  • uv run ruff check packages/memtomem/src
  • uv run pytest packages/memtomem/tests/test_i18n.py
    689→691-key parity / placeholder parity / empty-value
  • Mode 1 (uv run mm web) + Playwright MCP, KO locale:
    - Initial: badge hidden=true, textContent=""
    - After tag-filter='foo' + ns-filter=<first>: badge visible,
    textContent="2", aria-label="필터 2개 적용됨"
    - Clear ns-filter only: textContent="1",
    aria-label="필터 1개 적용됨"
    - Clear tag-filter too: hidden=true, aria-label removed
  • Manual: chip-✕ removal also drops the badge count, and the
    langchange toggle re-localizes the aria-label while a filter
    is applied

🤖 Generated with Claude Code

memtomem pushed a commit that referenced this pull request May 2, 2026
Review (#684) caught two restore paths that set ``tag-filter`` /
``chunk-type-filter`` and call ``doSearch()`` without first telling
the badge to recount:

- ``saved-queries-select`` change handler (the dropdown next to the
  Save / ✕ buttons in the Advanced panel),
- ``.saved-chip-name`` click handler in the saved-searches bar.

The badge eventually recovers because ``_renderActiveFilters`` runs
inside ``renderResults`` once the search returns, but in the gap
between the form being populated and the network round-trip
finishing the toggle button advertises stale numbers — and the PR
description explicitly promised "tracks the form before the user
even runs a search," so the gap is also a documentation lie.

Add a single ``_updateFilterCountBadge()`` call before each
``doSearch()`` so the badge updates synchronously with the form.

No new keys, no schema change. ``app.js`` is the only file touched
and the cache-bust ``v=90`` from the original PR commit still
covers it (the file content keeps moving under the same query
string until the PR lands).

Co-Authored-By: Claude <[email protected]>
pandas-studio and others added 2 commits May 2, 2026 10:57
The "▾ Filters" button only flipped to btn-active when the filter row
was open; how many filters were actually applied was visible only via
the chip row, which itself only renders alongside search results. Open
the filters, set a tag and a namespace, collapse the row, and the
button looked the same as if nothing was set.

Add a small accent-coloured count badge inside the toggle that mirrors
the chip set in _renderActiveFilters (namespace, tag, chunk type, score
threshold). The badge updates from four edges:

- input on tag-filter / change on ns-filter / change on
  chunk-type-filter / input on score-threshold so it tracks the form
  even before the user runs a search,
- _renderActiveFilters at search time so chip removals (clicking ✕ on a
  chip) keep the count honest,
- _loadSearchFromURL for the URL-restored case (?type=…),
- the langchange event so the aria-label localizes alongside the rest
  of the UI.

i18n adds search.filter_count_aria_one / _other in en + ko, following
the existing CLDR `_one`/`_other` pattern (see PR #608 and
index.upload_usage_count_*). Cache-bust style.css to v=74 and app.js to
v=90.

Verified end-to-end against Mode 1 (`uv run mm web`) with Playwright
MCP: badge starts hidden, shows "2" after a tag + ns are set, drops to
"1" when ns is cleared via change event, and hides again when both are
cleared. aria-label reads "필터 2개 적용됨" / "필터 1개 적용됨" under ko.

Co-Authored-By: Claude <[email protected]>
Review (#684) caught two restore paths that set ``tag-filter`` /
``chunk-type-filter`` and call ``doSearch()`` without first telling
the badge to recount:

- ``saved-queries-select`` change handler (the dropdown next to the
  Save / ✕ buttons in the Advanced panel),
- ``.saved-chip-name`` click handler in the saved-searches bar.

The badge eventually recovers because ``_renderActiveFilters`` runs
inside ``renderResults`` once the search returns, but in the gap
between the form being populated and the network round-trip
finishing the toggle button advertises stale numbers — and the PR
description explicitly promised "tracks the form before the user
even runs a search," so the gap is also a documentation lie.

Add a single ``_updateFilterCountBadge()`` call before each
``doSearch()`` so the badge updates synchronously with the form.

No new keys, no schema change. ``app.js`` is the only file touched
and the cache-bust ``v=90`` from the original PR commit still
covers it (the file content keeps moving under the same query
string until the PR lands).

Co-Authored-By: Claude <[email protected]>
@memtomem memtomem force-pushed the feat/search-filter-count-badge branch from b93263e to d1f1e09 Compare May 2, 2026 01:57
@memtomem memtomem merged commit 5020374 into main May 2, 2026
8 of 9 checks passed
@memtomem memtomem deleted the feat/search-filter-count-badge branch May 2, 2026 01:58
@github-actions github-actions Bot locked and limited conversation to collaborators May 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants