Skip to content

[do not merge] Search UX v2 #5: sidebar tri-state filters#665

Draft
hoyla wants to merge 1 commit into
ljh-searchux-v2-pr4-search-page-modalfrom
ljh-searchux-v2-pr5-sidebar-tristate
Draft

[do not merge] Search UX v2 #5: sidebar tri-state filters#665
hoyla wants to merge 1 commit into
ljh-searchux-v2-pr4-search-page-modalfrom
ljh-searchux-v2-pr5-sidebar-tristate

Conversation

@hoyla

@hoyla hoyla commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Note

THIS IS A PLACEHOLDER PR SO I CAN REMEMBER WHAT WAS DONE IN THIS BRANCH.
It'll probably get rewritten entirely should we actually get here.

Context

Part of the Search UX Improvements epic. Closes #637.

Important

This is the fifth and final PR in the Search UX Improvements epic.

PR1 Chip parsing infrastructure
 └─ PR2 Shared utilities & Downshift dependency
     └─ PR3 Active filter chips & multi-select
         └─ PR4 Search page & AddFilterModal
             └─ PR5 Sidebar tri-state filters  ← you are here

Changes to the user experience

Tri-state sidebar checkboxes

Sidebar filter checkboxes now cycle through three states: unchecked (no filter) → checked/blue (include) → indeterminate/red (exclude). This applies to Workspace, Dataset, and File Type filters.

File type category grouping

File type sidebar filters are grouped by human-readable category (Documents, Spreadsheets, Images, Audio, etc.) with result counts from Elasticsearch aggregations. Categories can be expanded to show individual MIME types.

Sidebar ↔ chip synchronisation

Sidebar selections now read from and write to the chip-based q parameter via chipParsing helpers (setWorkspacesInQ, setDatasetsInQ, setFileTypeCategoriesInQ). This means sidebar changes are reflected in the active filter chips and URL, and vice versa.

Bug fix

"Search this workspace" and "Search in folder" now embed workspace/folder as chips in q (same fix as PR4, applied here since these files are also modified in this branch).

What's included

  • SearchSidebar.tsx — full TypeScript conversion of SearchSidebar.js; integrates tri-state filter handling for workspaces, datasets, and file types. Reads positive/negative filter arrays from chips in q.
  • FileTypeSidebarFilter (FileTypeSidebarFilter.tsx) — new component grouping MIME types into categories using fileTypeCategories, with tri-state checkboxes, aggregation counts, and expandable sub-categories.
  • TriStateSidebarSection (TriStateSidebarSection.tsx) — generic tri-state sidebar section (used for workspace and dataset filters) with expandable options, aggregation bucket counts, and off → include → exclude cycling.
  • SCSS (_sidebar.scss) — styling updates for tri-state sidebar elements.

TypeScript

SearchSidebar.js converted to TypeScript with full type annotations.

Automated tests

  • FileTypeSidebarFilter.spec.tsx — unit tests with helpers for building mock ES aggregation buckets and constructing component instances with default props.

Manual tests

Tested locally. Tested on playground.

@hoyla hoyla added the feature Departmental tracking: work on a new feature label Apr 3, 2026
@hoyla hoyla changed the title Search UX v2 #5: sidebar tri-state filters [DO NOT MERGE] Search UX v2 #5: sidebar tri-state filters Apr 4, 2026
@hoyla hoyla changed the title [DO NOT MERGE] Search UX v2 #5: sidebar tri-state filters [do not merge] Search UX v2 #5: sidebar tri-state filters Apr 4, 2026
@hoyla
hoyla force-pushed the ljh-searchux-v2-pr4-search-page-modal branch from f599bc6 to 175c82a Compare April 9, 2026 09:52
@hoyla
hoyla force-pushed the ljh-searchux-v2-pr5-sidebar-tristate branch from efdc14c to 3ed50dc Compare April 11, 2026 07:05
@hoyla
hoyla force-pushed the ljh-searchux-v2-pr4-search-page-modal branch from 175c82a to 11de024 Compare May 17, 2026 16:32
@hoyla
hoyla force-pushed the ljh-searchux-v2-pr5-sidebar-tristate branch from 3ed50dc to 1cf2927 Compare May 17, 2026 16:34
@hoyla
hoyla force-pushed the ljh-searchux-v2-pr4-search-page-modal branch from 11de024 to aa11b2e Compare June 3, 2026 20:37
Convert SearchSidebar.js to SearchSidebar.tsx with TypeScript types
and chip-driven filters. The sidebar now reads the q (search query)
from Redux and routes three filter keys to new components:

- mimeType → FileTypeSidebarFilter: maps ES aggregation MIME
  buckets to FILE_TYPE_CATEGORIES using mimeToCategory(), shows
  category-level tri-state checkboxes (off→include→exclude→off),
  with expandable sub-items showing individual MIME counts.

- workspace → TriStateSidebarSection: generic tri-state section
  that reads/writes workspace chips via setWorkspacesInQ.

- ingestion → TriStateSidebarSection: reads/writes dataset chips
  via setDatasetsInQ.

All other filter keys continue to use the existing SearchFilter
component unchanged. The updateSelectedFilters callback now strips
workspace/ingestion from legacy filter updates since those are now
chip-driven.

Both new components use the shared triStateCycle utility from PR2
for the off→positive→negative→off cycling logic, and the
TriStateCheckbox component for rendering.

Fix TriStateCheckbox import path for triStateCycle (was resolving
to wrong directory).

Add sidebar__mime-info SCSS class for indented MIME sub-items.
Add FileTypeSidebarFilter.spec.tsx with 14 tests covering
buildCategoryCounts, toggleCategory, getCategoryState, and
toggleCategoryExpanded.
@hoyla
hoyla force-pushed the ljh-searchux-v2-pr5-sidebar-tristate branch from 1cf2927 to a2f101d Compare June 3, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚠️ do not merge feature Departmental tracking: work on a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant