[995] feat: add Partner filter to case studies page#251
Conversation
- Add Partner filter option in sidebar after Industry, Case Type, and Technology - Implement backend filtering logic for business-partner relationships - Update NavigationService, UrlService, and TagCountService to support partner filtering - Add partner filter UI matching existing filter patterns - Support multi-select and combination with other filters
WalkthroughThis PR adds "partner" as a first-class filter to the case-studies page: it registers the partner filter in the page configuration and admin, extends tag counting to produce partner counts, adds slug→ID conversion for partner slugs in NavigationService, includes partner query parameters in UrlService URL construction, and updates the case-studies-page view to render, select, and clear partner filters. Error-path fallbacks also include an empty partner map. Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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:15391aa5e0ca3a9febdde4707e70c9b7dafa603898c1bc54795002fa14e698b4 |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 172 MB |
| packages | 971 |
📦 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
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/services/NavigationService.js`:
- Around line 39-51: The two nearly identical methods convertPartnerSlugsToIds
and convertSlugsToIds should be collapsed into a single generic helper (e.g.,
convertSlugsToIdsForModule) that accepts (apos, req, slugs, moduleName), uses
apos.modules[moduleName].find(...).toArray(), and returns the aposDocId array;
replace both convertPartnerSlugsToIds and convertSlugsToIds usages in
applyFiltersToQuery to call this new helper with the appropriate module key
string (e.g., 'business-partner' or the other module name) and remove the
duplicated method(s).
In `@website/modules/case-studies-page/services/TagCountService.js`:
- Around line 65-72: fetchCaseStudiesAndTags currently awaits three independent
DB queries serially (caseStudies, casesTags, businessPartners); change it to run
them concurrently via Promise.all: invoke
aposModules[options.pieces].find(req).toArray(),
aposModules['cases-tags'].find(req).toArray(), and
aposModules['business-partner'].find(req).toArray() inside Promise.all and
destructure the results into caseStudies, casesTags, businessPartners before
returning them so the function returns the same [caseStudies, casesTags,
businessPartners] but with reduced latency.
- Around line 29-35: createPartnerMap duplicates createTagMap; replace both with
a single generic helper (e.g., createMapFromList) that accepts the list and the
key/value accessors, remove createPartnerMap, and update call sites in
calculateTagCounts to call the new generic function instead of
createPartnerMap/createTagMap so both partners and tags use the shared
implementation; target functions: createPartnerMap, createTagMap, and
calculateTagCounts when making the change.
website/modules/case-studies-page/services/NavigationService.js
Outdated
Show resolved
Hide resolved
…s, lint fixes in NavigationService and TagCountService
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/modules/case-studies-page/services/TagCountService.js (1)
7-7:⚠️ Potential issue | 🟡 MinorClass-level JSDoc is stale — partner counting not mentioned.
Line 7 lists responsibilities as "(industry, stack, case study type)" but the service now also counts partners. Keep the doc in sync.
- * - Counting tags by type (industry, stack, case study type) + * - Counting tags by type (industry, stack, case study type, partner)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/modules/case-studies-page/services/TagCountService.js` at line 7, Update the stale class JSDoc on TagCountService to reflect current responsibilities: add "partners" (or "partner") to the list of tag types being counted so the comment matches the implementation that counts industry, stack, case study type, and partners; locate the class JSDoc for TagCountService and edit the parenthetical (or bulleted) list to include partners.
🤖 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/services/NavigationService.js`:
- Around line 65-87: The applySlugFilter static method on NavigationService is
dead and has incompatible option names; remove the entire applySlugFilter method
(the static async applySlugFilter(filteredQuery, req, apos, options) function)
from NavigationService.js, ensure no other code or tests reference
NavigationService.applySlugFilter, and if any callers expected the old option
shape ({ paramName, convertFn, fieldName }) update them to use the existing
applyFiltersToQuery pattern (which uses { param, convert, field }) or delete
those callers/tests as dead code so filterConfigs remain consistent.
- Around line 19-31: convertSlugsToIdsForModule currently assumes slugs is an
array and will throw when a single string is passed; normalize the input at the
top of convertSlugsToIdsForModule by converting a string (or undefined) into an
array (e.g., if slugs is a string wrap it as [slugs], if falsy use an empty
array) before calling map, then proceed to fetch and return aposDocId values as
before; also address the related applySlugFilter: either remove this dead,
unused function or update callers to use it if intended (ensure any call sites
also pass arrays or rely on the same normalization).
---
Outside diff comments:
In `@website/modules/case-studies-page/services/TagCountService.js`:
- Line 7: Update the stale class JSDoc on TagCountService to reflect current
responsibilities: add "partners" (or "partner") to the list of tag types being
counted so the comment matches the implementation that counts industry, stack,
case study type, and partners; locate the class JSDoc for TagCountService and
edit the parenthetical (or bulleted) list to include partners.
website/modules/case-studies-page/services/NavigationService.js
Outdated
Show resolved
Hide resolved
… dead applySlugFilter
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/modules/case-studies-page/services/NavigationService.js (1)
141-141: 🧹 Nitpick | 🔵 TrivialRedundant
return awaitin two methods.
return awaitinside anasyncfunction is unnecessary when the awaited expression is immediately returned and there is no enclosingtry/catch— it adds an extra microtask tick and would be flagged by theno-return-awaitESLint rule.Lines 141 and 210 are both affected:
🔧 Proposed fix
- return await query.sort({ updatedAt: -1 }).toArray(); + return query.sort({ updatedAt: -1 }).toArray();- return await NavigationService.getNavigationData( + return NavigationService.getNavigationData( req, apos, pageModule, currentPiece, );Also applies to: 210-215
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/modules/case-studies-page/services/NavigationService.js` at line 141, Remove the redundant "return await" in the async methods that immediately return the Promise (no enclosing try/catch): replace occurrences like "return await query.sort({ updatedAt: -1 }).toArray();" with "return query.sort({ updatedAt: -1 }).toArray();" and do the same for the other affected return (lines ~210–215) in NavigationService.js so the async function returns the Promise directly.
🤖 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/services/NavigationService.js`:
- Line 43: Update the JSDoc for the wrapper methods that call
convertSlugsToIdsForModule to reflect that the slugs parameter can be either a
string or an array (not just Array); change the `@param` annotation from {Array}
slugs to {string|Array} or {string|string[]} (or similar) in the JSDoc blocks
for the wrappers that reference slugs so the documentation matches
convertSlugsToIdsForModule which explicitly accepts a string input.
- Around line 27-28: Guard against an undefined module before calling .find by
checking apos.modules[moduleKey] (identify via the moduleKey variable and the
apos.modules lookup in NavigationService.js) and handle the missing-module case
explicitly: if the module is not registered, log or throw a descriptive error
mentioning the offending moduleKey and return/skip gracefully (e.g., return an
empty result or continue to the next config) instead of calling .find on
undefined; ensure this check is performed before invoking .find(...) so the
resulting error clearly identifies the bad key.
---
Outside diff comments:
In `@website/modules/case-studies-page/services/NavigationService.js`:
- Line 141: Remove the redundant "return await" in the async methods that
immediately return the Promise (no enclosing try/catch): replace occurrences
like "return await query.sort({ updatedAt: -1 }).toArray();" with "return
query.sort({ updatedAt: -1 }).toArray();" and do the same for the other affected
return (lines ~210–215) in NavigationService.js so the async function returns
the Promise directly.
feat: add Partner filter to case studies page
Adds a multi-select "Partner" filter to the Case Studies page (sidebar UI and admin), with end-to-end support: URL query handling, backend slug→ID conversion, filter application, and tag counting. NavigationService gained generic slug-to-ID and filter application helpers; TagCountService now counts partners; UrlService builds partner query params—enabling combined filtering with industry, case type, and technology.