Skip to content

feat: support filtering search results by category - #712

Merged
qiancai merged 6 commits into
pingcap:masterfrom
qiancai:add-search-filters
Jul 22, 2026
Merged

feat: support filtering search results by category#712
qiancai merged 6 commits into
pingcap:masterfrom
qiancai:add-search-filters

Conversation

@qiancai

@qiancai qiancai commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Search results can span multiple documentation areas in a single query. Without filtering, users must scan a long mixed list to find hits in the section they care about.

This PR adds category filtering to the on-site search results page, so users can narrow results by documentation category (for example, TiDB Self-Managed, TiDB Cloud, or Developer) and easily return to the complete result set.

Preview

By default, the doc site displays the complete search results. If the results contain at least two categories, the filter bar is displayed.

img_v3_0213r_92965b02-4dba-455a-8c11-2f3a3c3aa2dg

Users can click a category label to show only results in that category.

8ysz5G0M17

What changed

  • src/templates/DocSearchTemplate.tsx: Track the active category filter, derive the available categories from Algolia results, filter the displayed list client-side, and reset the filter when the query or language changes.
  • src/components/Search/Results.tsx: Add a SearchFilterBar with an initially selected All chip followed by category chips. Filter state changes are immediate without click or hover animation. The category tags shown beside individual result URLs remain display-only and are not clickable.
  • locale/en/translation.json, locale/zh/translation.json, and locale/ja/translation.json: Add localized labels for the filter bar and the All-results option.

Implementation

  • Reuse the existing resolveSearchCategory() utility (shared/utils/searchCategory.ts) to classify each hit by URL path. No Algolia index or query changes are required.
  • Build a set of available categories from the raw search hits and show the filter bar only when results span more than one valid category.
  • Treat activeFilter === null as the All-results state, which is selected by default.
  • Filter results with useMemo. Clicking a category chip applies that category; clicking it again or clicking All clears the filter and restores the complete result set.
  • Keep the category tags beside individual result URLs non-interactive so filtering is controlled only from the filter bar.

Test plan

  • Run a search that returns hits across multiple categories (for example, backup) and confirm the filter bar appears with All first, followed by category chips.
  • Confirm All is selected by default and the complete result set is displayed.
  • Click a category chip and verify that only matching results are shown and the selected style moves to that chip without a flash animation.
  • Hover over the selected chip and confirm it remains black.
  • Click All and verify that the complete result set is restored; click an active category again and verify it also returns to All.
  • Confirm category tags beside individual result URLs are not clickable.
  • Run a new search or clear the query and confirm the filter resets to All.
  • Verify the English, Chinese, and Japanese translation resources contain the filter labels.

Summary by CodeRabbit

  • New Features

    • Added category-based filtering for search results with localized filter chip labels and an “all results” option.
    • Filter chips appear only when filtering is applicable (not loading and with more than one valid category).
    • Updated English, Japanese, and Chinese translations to support the new filter UI.
  • Bug Fixes

    • Clear the active filter when the query is empty/invalid, when locale indexing can’t be resolved, and after searches complete (success or failure) to avoid showing stale filtered results.
    • On initial URL load, the filter is reset and loading state is adjusted for Japanese locale.

@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

@qiancai is attempting to deploy a commit to the test-vi Team on Vercel.

A member of the Team first needs to authorize it.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a search filtering feature for the documentation search page, allowing users to filter search results by category. It adds a new SearchFilterBar component, updates SearchResults and SearchItem to support filter changes, and manages the active filter state in DocSearchTemplate. The feedback suggests making the category chip's interactivity conditional on the presence of the onFilterChange callback, and filtering out categories without valid translation labels before rendering the filter bar to prevent rendering redundant or empty states.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/components/Search/Results.tsx Outdated
Comment thread src/components/Search/Results.tsx Outdated
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Search results now support category filtering. The template derives categories and filtered results, while search components render localized filter chips. Filter state resets across search lifecycle paths, with English, Japanese, and Chinese translations updated.

Changes

Search filtering

Layer / File(s) Summary
Filter controls and clickable result categories
src/components/Search/Results.tsx
SearchFilterBar renders localized category chips with active styling and invokes callbacks when filters change.
Template filtering state and rendering
src/templates/DocSearchTemplate.tsx
DocSearchTemplate categorizes results, tracks and resets the active filter, computes filtered results, and wires the filter bar into the layout.
Localized filter labels
locale/en/translation.json, locale/ja/translation.json, locale/zh/translation.json
Translations add filter-related labels for the search interface and result guidance.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

A rabbit taps a filter chip,
And tidy search results gently flip.
New labels guide each hopping feat,
While matching pages line up neat.
“Search is sorted!” sings the bunny bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding category-based filtering to search results.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/components/Search/Results.tsx (1)

93-103: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove commented-out dead code.

This block of commented-out JSX appears to be obsolete. Removing it will keep the file clean and improve readability.

♻️ Proposed refactor
-      {/* <Typography
-        variant="body2"
-        sx={{
-          paddingBottom: "2rem",
-        }}
-      >
-        <Trans
-          i18nKey="search.resultTips.counts"
-          values={{ data.length }}
-        />
-      </Typography> */}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Search/Results.tsx` around lines 93 - 103, Remove the
commented-out JSX block containing Typography and Trans from the Results
component, leaving the surrounding live rendering logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/Search/Results.tsx`:
- Around line 93-103: Remove the commented-out JSX block containing Typography
and Trans from the Results component, leaving the surrounding live rendering
logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1bb4882c-b2ee-43f0-a9e1-8bfe874ad26a

📥 Commits

Reviewing files that changed from the base of the PR and between 9ddc03f and b501ffe.

📒 Files selected for processing (4)
  • locale/en/translation.json
  • locale/zh/translation.json
  • src/components/Search/Results.tsx
  • src/templates/DocSearchTemplate.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/templates/DocSearchTemplate.tsx (1)

99-113: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Prevent stale searches from replacing the current results.

Overlapping Algolia requests are not sequenced. An older request can resolve after a newer query—or after the query is cleared—and restore stale hits, clear the active filter, and prematurely end loading. Track a request generation or cancel prior requests; invalidate it for the early-return paths too.

Proposed fix
+  const searchRequestId = React.useRef(0);
+
   const execSearch = React.useCallback(
     (query: string) => {
+      const requestId = ++searchRequestId.current;
       const trimmedQuery = query.trim();
       // ...
       index.search(trimmedQuery, { hitsPerPage: 150 })
         .then(({ hits }) => {
+          if (requestId !== searchRequestId.current) return;
           setResults(hits);
           setActiveFilter(null);
           setIsLoading(false);
         })
         .catch((reason: any) => {
+          if (requestId !== searchRequestId.current) return;
           console.error(reason);
           setResults([]);
           setActiveFilter(null);
           setIsLoading(false);
         });
     },
     [language]
   );
 
   React.useEffect(() => {
     // ...
     if (language === Locale.ja || !query.trim()) {
+      searchRequestId.current += 1;
       // clear state
       return;
     }

Also applies to: 118-135

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/templates/DocSearchTemplate.tsx` around lines 99 - 113, Update the search
flow in DocSearchTemplate to sequence or cancel overlapping requests so only the
latest query can update results, activeFilter, or loading state. Invalidate the
current request generation when the query is cleared or other early-return paths
execute, and apply the same guard to both success and catch handlers around
index.search.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/templates/DocSearchTemplate.tsx`:
- Around line 55-62: The search filter contract currently tracks only category
presence, so required result counts are missing. In
src/templates/DocSearchTemplate.tsx lines 55-62, replace the category Set
derivation with a category-to-count Map and retain the total result count; in
lines 167-172, pass both values to SearchFilterBar. In
src/components/Search/Results.tsx lines 303-354, update the All and category
chip labels to append the total and corresponding category counts.

---

Outside diff comments:
In `@src/templates/DocSearchTemplate.tsx`:
- Around line 99-113: Update the search flow in DocSearchTemplate to sequence or
cancel overlapping requests so only the latest query can update results,
activeFilter, or loading state. Invalidate the current request generation when
the query is cleared or other early-return paths execute, and apply the same
guard to both success and catch handlers around index.search.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ceef1ee8-d282-4025-a45c-699f288b0b50

📥 Commits

Reviewing files that changed from the base of the PR and between 12d5c93 and 5488353.

📒 Files selected for processing (2)
  • src/components/Search/Results.tsx
  • src/templates/DocSearchTemplate.tsx

Comment thread src/templates/DocSearchTemplate.tsx
@qiancai
qiancai merged commit 9c64020 into pingcap:master Jul 22, 2026
1 of 2 checks passed
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.

2 participants