Skip to content

fix(theme/bootstrap): reset in-memory facet state on navigation#3173

Closed
marevol wants to merge 1 commit into
masterfrom
fix/bootstrap-theme-facet-reset-on-navigation
Closed

fix(theme/bootstrap): reset in-memory facet state on navigation#3173
marevol wants to merge 1 commit into
masterfrom
fix/bootstrap-theme-facet-reset-on-navigation

Conversation

@marevol

@marevol marevol commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

In the bootstrap SPA search theme, selecting a label via the sidebar facet and
then refining the search through the search-options panel keeps the previously
selected facet applied, even though it is no longer part of the new selection.

Steps to reproduce:

  1. Search for a term that has more than one label facet.
  2. Click a label in the sidebar facet (label A) -> results filtered to A.
  3. Open the search-options panel and select only a different label (label B).
  4. Submit.
  • Expected: only label B is applied.
  • Actual: both label A and label B are applied. The active-filter chips show
    both and the result count reflects both labels, even though the URL only
    contains fields.label=B.

Root cause

Filter state is kept client-side in two stores:

  • state.facets — written only by sidebar facet clicks. Facet clicks call
    runSearch() directly, so the selection is never serialized to the URL.
  • state.fields — written by the search-options label dropdown.

runFromUrl() re-derives state from the URL on every navigation, but it only
reset state.fields / lang / geo / exQ, leaving state.facets,
state.facetQueries and the similar-docs hash (state.sdh) intact. The
search-options submit navigates with only fields.* in the URL, so the stale
state.facets survived and runSearch() merged both stores together.

Fix

Reset state.facets, state.facetQueries and state.sdh in runFromUrl() so
the URL is the single source of truth on every navigation (search-options
submit, header search, browser back/forward). Paging and facet clicks call
runSearch() directly without navigating, so an active facet still persists
within the same result view as before.

The same reset already ships in the derived SPA themes in codelibs/fess-themes;
this aligns the canonical bootstrap theme in core. The filter-only-search
behavior added in #3171 is preserved — only the three memory-only stores are
reset, and the empty-keyword guard logic is left intact.

Testing

  • node --check on the modified file passes.
  • Traced the control flow in search.js (facet click handler, search-options
    submit handler, runFromUrl, the runSearch field merge, and pagination).
    Confirmed the stale stores are cleared on navigation and that paging/facet
    interactions are unaffected because they do not navigate.

Supersedes #3170, which was branched before #3171 and would otherwise revert
that change.

The bootstrap SPA search theme keeps filter state in two in-memory stores:

- state.facets: written only by sidebar facet clicks, which call runSearch()
  directly and never serialize the selection to the URL.
- state.fields: written by the search-options label dropdown and serialized to
  the URL as fields.*.

runSearch() merges both stores into the request. runFromUrl() re-derives state
from the URL on every navigation but did not reset the memory-only stores, so a
label chosen via the facet sidebar survived a later search-options submit: the
URL carried only the new label, yet the stale facet label was merged back in,
applying both labels and showing both as active-filter chips.

Reset state.facets, state.facetQueries and state.sdh in runFromUrl() so the URL
is the single source of truth on every navigation. The same reset already ships
in the derived SPA themes in codelibs/fess-themes; this aligns the canonical
bootstrap theme in core. The filter-only-search behavior added in #3171 is
preserved (the empty-keyword guard is left intact).
@marevol

marevol commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Closing as redundant. The facet-state reset this PR adds already landed in master via #3170, which resets state.facets / state.facetQueries / state.sdh in runFromUrl() and preserves the filter-only-search behavior from #3171. This branch was cut from an older local master, so merging it would also revert the no-op home-option helper cleanup in #3172. No change needed.

@marevol marevol closed this Jun 22, 2026
@marevol marevol deleted the fix/bootstrap-theme-facet-reset-on-navigation branch June 22, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant