[1025] Extend Search on Case Studies Page to All Fields#263
[1025] Extend Search on Case Studies Page to All Fields#263IhorMasechko merged 5 commits intomainfrom
Conversation
WalkthroughThe case-studies search was made relationship-aware: SearchService adds Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
🔍 Vulnerabilities of
|
| digest | sha256:f6f3af7589371b85e7d0e76c3ec89d0b1cba1705aab36b5a266fe83f888be8c4 |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 173 MB |
| packages | 975 |
📦 Base Image node:24-alpine
Description
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@website/modules/case-studies-page/index.js`:
- Around line 50-84: The runApplyEnhancedSearchResults function currently
fetches all matching pieces unpaginated because piecesQuery lacks a per-page
limit and totalQuery.toCount() is redundant; update piecesQuery (and totalQuery
if you still use it) to apply pagination by calling .perPage(perPage) (use the
incoming query param perPage or the module default perPage option from self)
before .toArray(), replace totalQuery.toCount() with using pieces.length for the
count (or compute totalPages from the actual perPage and count), and set
reqData.totalPages = Math.ceil(pieces.length / perPage) (or compute totalPieces
then totalPages) so infinite scroll triggers correctly; key symbols:
runApplyEnhancedSearchResults, piecesQuery, totalQuery, .perPage(), toArray(),
toCount(), reqData.pieces, reqData.totalPieces, reqData.totalPages.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: bc732837-8764-4152-8502-d69d3c22bb05
📒 Files selected for processing (6)
website/modules/case-studies-page/index.jswebsite/modules/case-studies-page/services/NavigationService.jswebsite/modules/case-studies-page/services/SearchService.jswebsite/modules/case-studies-page/views/index.htmlwebsite/public/js/modules/case-studies-page/infinite-scroll.jswebsite/public/js/modules/case-studies-page/search-handler.js
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
website/public/js/modules/case-studies-page/infinite-scroll.js (1)
88-100:⚠️ Potential issue | 🟡 MinorPage advances even when all cards are duplicates.
If the server returns cards that are all already displayed (e.g., due to stale pagination),
currentPageincrements but no visible content appears. Users may see the scroll trigger activate without new cards appearing.Consider tracking whether any cards were actually added and only incrementing
currentPageif so, or displaying a message when no new content was added.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/public/js/modules/case-studies-page/infinite-scroll.js` around lines 88 - 100, The current loop over newCards (newCards.forEach / getCardUrl / existingCardUrls / grid.appendChild) advances currentPage and resets errorCount/isLoading even when every returned card was a duplicate and nothing was appended; change the logic to track whether any card was actually added (e.g., a boolean like anyAppended set when grid.appendChild is called) and only update currentPage, reset errorCount, and set isLoading = false when anyAppended is true; if no cards were appended, avoid advancing currentPage and instead handle the empty-result case (show a “no new content” message or stop further fetch attempts) so the UI doesn’t trigger repeated empty loads.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@website/modules/case-studies-page/index.js`:
- Around line 56-59: The fallback assignment for perPage is redundant because
module options already set self.perPage = 6; remove the defensive block and use
self.perPage (or destructure const { perPage } = self) directly in the code path
that follows; update any references relying on the temporary variable to
reference perPage from self (e.g., replace the let { perPage } = self; if
(!perPage) { perPage = 6; } snippet with a direct const { perPage } = self or
just use self.perPage where needed in the case-studies-page module).
In `@website/public/js/modules/case-studies-page/infinite-scroll.js`:
- Around line 48-60: The fetchWithFallback function silently drops the `search`
param on 404 which can confuse users; update the address bar or surface a
notification when you use the fallback. Modify fetchWithFallback so after
creating fallbackUrl and before re-fetching you call history.replaceState(null,
'', fallbackUrl.toString()) to update the URL (or call an existing UI helper
like showNotification / dispatch a custom event) and ensure the UI/search input
reflects the removed parameter; reference function fetchWithFallback, variable
fallbackUrl, and helper hasActiveSidebarFilters to locate the code and keep the
fallback fetch behavior otherwise unchanged.
---
Outside diff comments:
In `@website/public/js/modules/case-studies-page/infinite-scroll.js`:
- Around line 88-100: The current loop over newCards (newCards.forEach /
getCardUrl / existingCardUrls / grid.appendChild) advances currentPage and
resets errorCount/isLoading even when every returned card was a duplicate and
nothing was appended; change the logic to track whether any card was actually
added (e.g., a boolean like anyAppended set when grid.appendChild is called) and
only update currentPage, reset errorCount, and set isLoading = false when
anyAppended is true; if no cards were appended, avoid advancing currentPage and
instead handle the empty-result case (show a “no new content” message or stop
further fetch attempts) so the UI doesn’t trigger repeated empty loads.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: df65e8b5-ec83-460d-b394-fe2e5c4c563a
📒 Files selected for processing (3)
website/modules/case-studies-page/index.jswebsite/public/js/modules/case-studies-page/infinite-scroll.jswebsite/public/js/modules/case-studies-page/infinite-scroll.test.js
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
website/modules/case-studies-page/index.js (1)
112-124:⚠️ Potential issue | 🟠 MajorPagination still disabled when relationship matches exist.
piecesQuery(line 112-114) lacks.perPage(self.perPage), sotoArray()fetches all matching results unpaginated. Line 122 hardcodestotalPages = 1, disabling infinite scroll regardless of result count. This bypasses theperPage: 6setting defined in module options.Apply pagination to enhanced search results
const piecesQuery = self.pieces .find(req, {}) - .applyBuildersSafely(queryParams); + .applyBuildersSafely(queryParams) + .perPage(self.perPage); piecesQuery.and(searchCondition); - const pieces = await piecesQuery.toArray(); - const totalPieces = pieces.length; + const countQuery = self.pieces.find(req, {}).applyBuildersSafely(queryParams); + countQuery.and(searchCondition); + + const pieces = await piecesQuery.toArray(); + const totalPieces = await countQuery.toCount(); const piecesFilters = await buildPiecesFiltersFromResults(self, req, pieces); reqData.pieces = pieces; reqData.totalPieces = totalPieces; - reqData.totalPages = 1; + reqData.totalPages = Math.max(1, Math.ceil(totalPieces / self.perPage)); reqData.piecesFilters = piecesFilters;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/modules/case-studies-page/index.js` around lines 112 - 124, piecesQuery is currently unpaginated and totalPages is hardcoded; call piecesQuery.perPage(self.perPage) before fetching so reqData.pieces contains the paginated results, compute totalPieces from the full matching count (e.g., piecesQuery.count() or the query API that returns total) and set reqData.totalPages = Math.ceil(totalPieces / self.perPage) instead of 1; update references to piecesQuery, .perPage(self.perPage), .toArray(), totalPieces and totalPages and keep buildPiecesFiltersFromResults using the paginated items as needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@website/modules/asset/ui/src/scss/_cases.scss`:
- Around line 796-802: The .cs_empty-state-title rule is failing stylelint’s
declaration-empty-line-before check; insert a single blank line before the
font-weight declaration so there is an empty line after the `@include`
responsive-line-height(...) directive. Update the .cs_empty-state-title block to
have a blank line separating the include lines from font-weight (target symbol:
.cs_empty-state-title and the font-weight: $font-weight-extra-bold declaration).
In `@website/modules/case-studies-page/index.js`:
- Around line 215-220: The methods resolveSearchRelationships and
applyEnhancedSearchResults use redundant "return await" when simply returning
the promise from runResolveSearchRelationships(self, req) and
runApplyEnhancedSearchResults(self, req); remove the "await" and just return the
promise (i.e., change "return await runResolveSearchRelationships(...)" to
"return runResolveSearchRelationships(...)" and similarly for
runApplyEnhancedSearchResults) to simplify the async methods — keep "await" only
if you add a try/catch that needs to observe thrown errors.
---
Duplicate comments:
In `@website/modules/case-studies-page/index.js`:
- Around line 112-124: piecesQuery is currently unpaginated and totalPages is
hardcoded; call piecesQuery.perPage(self.perPage) before fetching so
reqData.pieces contains the paginated results, compute totalPieces from the full
matching count (e.g., piecesQuery.count() or the query API that returns total)
and set reqData.totalPages = Math.ceil(totalPieces / self.perPage) instead of 1;
update references to piecesQuery, .perPage(self.perPage), .toArray(),
totalPieces and totalPages and keep buildPiecesFiltersFromResults using the
paginated items as needed.
🪄 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: ASSERTIVE
Plan: Pro
Run ID: 1bfa0a76-d4fc-4c1f-a656-c6d7c979e07a
📒 Files selected for processing (3)
website/modules/asset/ui/src/scss/_cases.scsswebsite/modules/case-studies-page/index.jswebsite/modules/case-studies-page/views/index.html
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
website/modules/case-studies-page/index.js (1)
112-123:⚠️ Potential issue | 🟠 MajorPagination still disabled when relationship matches exist.
The query at lines 112-114 lacks
.perPage(self.perPage), sotoArray()fetches all matching pieces unpaginated. Line 122 hardcodestotalPages = 1, breaking infinite scroll since the template checkscurrentPage < totalPages.This appears to be the same issue flagged in the previous review cycle. The fix mentioned (adding
.perPage(perPage)and computingtotalPages = Math.max(1, Math.ceil(totalPieces / perPage))) doesn't appear in the current code.Apply pagination to enhanced search results
const piecesQuery = self.pieces .find(req, {}) - .applyBuildersSafely(queryParams); + .applyBuildersSafely(queryParams) + .perPage(self.perPage); piecesQuery.and(searchCondition); - const pieces = await piecesQuery.toArray(); - const totalPieces = pieces.length; + const countQuery = self.pieces.find(req, {}).applyBuildersSafely(queryParams); + countQuery.and(searchCondition); + + const [pieces, totalPieces] = await Promise.all([ + piecesQuery.toArray(), + countQuery.toCount(), + ]); const piecesFilters = await buildPiecesFiltersFromResults(self, req, pieces); reqData.pieces = pieces; reqData.totalPieces = totalPieces; - reqData.totalPages = 1; + reqData.totalPages = Math.max(1, Math.ceil(totalPieces / self.perPage)); reqData.piecesFilters = piecesFilters;,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/modules/case-studies-page/index.js` around lines 112 - 123, The enhanced search results are not paginated because piecesQuery is missing .perPage(self.perPage) and totalPages is hardcoded to 1; update the query pipeline used in build (the piecesQuery created via self.pieces.find(...).applyBuildersSafely(...)) to call .perPage(self.perPage) before awaiting .toArray(), then compute reqData.totalPages = Math.max(1, Math.ceil(totalPieces / self.perPage)) (keep reqData.pieces and reqData.totalPieces as-is) so the template’s currentPage < totalPages logic works correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@website/modules/case-studies-page/index.js`:
- Around line 91-124: The function runApplyEnhancedSearchResults lacks error
handling around its async database operations (creating piecesQuery, calling
piecesQuery.toArray(), and buildPiecesFiltersFromResults) so any failure will
crash rendering; wrap the body of runApplyEnhancedSearchResults (or at minimum
the section from creating piecesQuery through awaiting
buildPiecesFiltersFromResults) in a try/catch, log the error (or attach to
req.data as appropriate), and return early (e.g., return undefined) to allow the
caller to fall back to standard search behavior; reference
runApplyEnhancedSearchResults, piecesQuery, piecesQuery.toArray,
buildPiecesFiltersFromResults and req.data when locating where to add the
try/catch.
---
Duplicate comments:
In `@website/modules/case-studies-page/index.js`:
- Around line 112-123: The enhanced search results are not paginated because
piecesQuery is missing .perPage(self.perPage) and totalPages is hardcoded to 1;
update the query pipeline used in build (the piecesQuery created via
self.pieces.find(...).applyBuildersSafely(...)) to call .perPage(self.perPage)
before awaiting .toArray(), then compute reqData.totalPages = Math.max(1,
Math.ceil(totalPieces / self.perPage)) (keep reqData.pieces and
reqData.totalPieces as-is) so the template’s currentPage < totalPages logic
works correctly.
🪄 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: ASSERTIVE
Plan: Pro
Run ID: b19a7b5a-7c51-492d-aa42-3bae95b268e9
📒 Files selected for processing (2)
website/modules/asset/ui/src/scss/_cases.scsswebsite/modules/case-studies-page/index.js
Enhance case studies search for text and taxonomy fields
This PR expands case-studies search to cover multiple text fields (title, portfolioTitle, descriptor, objective, challenge, solution, results) and related taxonomy fields (stacks, industries, case study types, partners). It adds SearchService.resolveSearchRelationships, passes resolved matches into buildSearchCondition, updates server/navigation hooks, introduces enhanced result handling, improves infinite-scroll de-duplication/retry, and adds a centered empty-state UI and accessibility tweaks.