Skip to content

Update recommended content for search panel#250

Merged
CodyWMitchell merged 2 commits intoRedHatInsights:masterfrom
CodyWMitchell:update-recommended-content
Mar 5, 2026
Merged

Update recommended content for search panel#250
CodyWMitchell merged 2 commits intoRedHatInsights:masterfrom
CodyWMitchell:update-recommended-content

Conversation

@CodyWMitchell
Copy link
Copy Markdown
Contributor

RHCLOUD-45386

Updates the recommended content within the search panel tab (All and per bundle)

RecommendedItems

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 4, 2026

Summary by CodeRabbit

  • New Features

    • Enhanced recommended content in HelpPanel search with bundle-aware and fallback recommendations, capped results, and improved initial toggle behavior.
    • Added bookmark icons for quickstart/quickstart-like items and clearer bundle labeling.
  • Tests

    • Broadened test coverage for recommended content, bundle/all toggles, dynamic search behavior, tab interactions, accessibility, and Virtual Assistant scenarios.
    • Expanded test scaffolding and API mocking for more realistic behaviors.

Walkthrough

Refactors SearchPanel to compute recommended content from a new static/dynamic config and a one-time quickstarts load; derives bundle context synchronously from chrome bundle APIs; adds a recommendedContentConfig module and expands component tests with extensive API and chrome mocks.

Changes

Cohort / File(s) Summary
Test Infrastructure
cypress/component/HelpPanel.cy.tsx
Extended test Wrapper to accept an injectable api; added richer test scaffolding and intercepts for quickstarts endpoints, filters, favorites, static API-specs/bundles JSON; introduced a mock chromeApi (getBundleData, getAvailableBundles, auth.getUser) and expanded SearchPanel test coverage (recommended content, search behavior, tabs, VA flows, accessibility).
Recommended Content Config
src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts
New module exporting RecommendedItem type, RECOMMENDED_CONTENT_LIMIT (5), bundleRecommendedContent (per-bundle static/dynamic recommendation lists), and defaultRecommendedContent fallback.
SearchPanel Core Logic
src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx
Refactored from async on-demand recommended loading to: synchronous bundle context via chrome.getBundleData/chrome.getAvailableBundles, one-time mount fetch of allQuickStarts, memoized computedRecommendedContent, utilities resolveRecommendedItems and buildFallbackRecommendedContent, and updated toggle/home-page logic and prop usage (displayBundleName).
SearchPanel Presentation
src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchResultItem.tsx
Added BookmarkIcon and set it as the icon for the quickstart breadcrumb type.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test Wrapper / Browser
    participant Scalprum as Scalprum / App Init
    participant Chrome as chrome API
    participant Quickstarts as Quickstarts API
    participant Search as SearchPanel

    Test->>Scalprum: mount HelpPanel (with optional api)
    Scalprum->>Chrome: chrome.getBundleData() / getAvailableBundles()
    Chrome-->>Scalprum: bundle metadata
    Scalprum->>Search: provide displayBundleName, bundleId
    Search->>Quickstarts: fetch all quickstarts (on mount)
    Quickstarts-->>Search: quickstarts payload (data / body)
    Search->>Search: resolveRecommendedItems / buildFallbackRecommendedContent (uses recommendedContentConfig + allQuickStarts)
    Search-->>Test: render UI (Recommended content, toggles, tabs)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update recommended content for search panel' accurately summarizes the main change: updating the recommended content display in the search panel component.
Description check ✅ Passed The description references the Jira issue RHCLOUD-45386 and clearly describes updating recommended content in the search panel tab, which aligns with the changeset's purpose and scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts`:
- Line 45: Typo in several recommendation title strings: change "documenation"
to "documentation" in the title properties of the recommended content entries
defined in recommendedContentConfig (look for objects with title: 'Related
documenation for OpenShift Cluster Manager' and similar variants); update each
title string occurrence so it reads "Related documentation for OpenShift Cluster
Manager" (ensure you fix all instances in the recommendedContentConfig
definitions).

In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx`:
- Around line 401-403: computedRecommendedContent currently returns [] whenever
allQuickStarts is empty which hides static/curated recommendations; remove the
early return and instead initialize the recommendations from the static/curated
source (e.g., curatedRecommendations or staticRecommendedContent) and then
conditionally merge in quick-start items only if allQuickStarts.length > 0, or
filter/transform quickstarts when present; update the useMemo block around
computedRecommendedContent to build from the curated list first and append or
interleave allQuickStarts when available rather than short-circuiting to an
empty array.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 529fddfc-c791-489f-b120-14e35e183994

📥 Commits

Reviewing files that changed from the base of the PR and between a77930d and 5e6efdb.

📒 Files selected for processing (4)
  • cypress/component/HelpPanel.cy.tsx
  • src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx
  • src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchResultItem.tsx
  • src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts

Comment thread src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts Outdated
Comment on lines +401 to +403
const computedRecommendedContent = useMemo(() => {
if (allQuickStarts.length === 0) return [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Do not gate all recommendations on quickstart data availability.

Returning [] when allQuickStarts is empty suppresses static curated recommendations, so users can see an empty recommended section even when static config exists.

Suggested fix
-  const computedRecommendedContent = useMemo(() => {
-    if (allQuickStarts.length === 0) return [];
-
+  const computedRecommendedContent = useMemo(() => {
     const showBundleContent =
       activeToggle === 'bundle' && !isHomePage && bundleId;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx` around
lines 401 - 403, computedRecommendedContent currently returns [] whenever
allQuickStarts is empty which hides static/curated recommendations; remove the
early return and instead initialize the recommendations from the static/curated
source (e.g., curatedRecommendations or staticRecommendedContent) and then
conditionally merge in quick-start items only if allQuickStarts.length > 0, or
filter/transform quickstarts when present; update the useMemo block around
computedRecommendedContent to build from the curated list first and append or
interleave allQuickStarts when available rather than short-circuiting to an
empty array.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx (2)

204-205: Avoid re-fetching quickstarts during search when already loaded.

Quickstarts are loaded on mount (allQuickStarts) and then fetched again per search query. Reusing allQuickStarts when present will reduce request volume and improve perceived latency.

Also applies to: 383-390

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx` around
lines 204 - 205, The search handler is re-fetching quickstarts via fetchAllData
even when allQuickStarts is already loaded; update the logic in SearchPanel (the
spots using fetchAllData to get quickStarts) to first check the existing
allQuickStarts state and reuse it if non-empty, only calling
fetchAllData(chrome.auth.getUser, {}) to obtain quickStarts when allQuickStarts
is empty or undefined; apply this change to the occurrence around the const [,
quickStarts] = await fetchAllData(...) and the duplicate block referenced (the
second occurrence around lines 383–390) so searches use cached allQuickStarts
and avoid redundant network requests.

405-419: Backfill curated recommendations to the configured limit.

Current logic returns curated results whenever resolved.length > 0, so missing dynamic items can leave the list underfilled even when fallback items are available. Consider topping up from fallback (with de-duplication) to reach RECOMMENDED_CONTENT_LIMIT.

Proposed fix
     if (showBundleContent) {
       const curatedItems = bundleRecommendedContent[bundleId];
       if (curatedItems?.length) {
         const resolved = resolveRecommendedItems(curatedItems, allQuickStarts);
-        if (resolved.length > 0) return resolved;
+        if (resolved.length >= RECOMMENDED_CONTENT_LIMIT) return resolved;
+
+        const fallback = buildFallbackRecommendedContent(allQuickStarts, true);
+        const seen = new Set(resolved.map((item) => item.id));
+        const topUp = fallback.filter((item) => !seen.has(item.id));
+        return [...resolved, ...topUp].slice(0, RECOMMENDED_CONTENT_LIMIT);
       }
       return buildFallbackRecommendedContent(allQuickStarts, true);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx` around
lines 405 - 419, When showBundleContent is true the code returns curated items
as soon as resolveRecommendedItems(curatedItems, allQuickStarts) yields any
results, which can leave the returned list shorter than
RECOMMENDED_CONTENT_LIMIT; change the logic in the showBundleContent branch
(using bundleRecommendedContent[bundleId], bundleId, resolveRecommendedItems and
allQuickStarts) to, after resolving curated items, call
buildFallbackRecommendedContent(allQuickStarts, true) and append fallback items
(skipping duplicates by id or unique key) until the combined list reaches
RECOMMENDED_CONTENT_LIMIT, then return that topped-up list; apply the same
topping-up + de-duplication behavior when defaultResolved (from
defaultRecommendedContent) is non-empty so both curated and default flows fill
to the configured limit.
src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts (1)

61-137: Consider de-duplicating the rhel and insights recommendation blocks.

Those two arrays are effectively the same content today, so keeping both copies will make future edits easy to miss in one path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts`
around lines 61 - 137, The rhel and insights arrays in
recommendedContentConfig.ts are duplicated; extract the common entries into a
single shared constant (e.g., baseRecommendations or COMMON_RECOMMENDATIONS) and
replace the rhel and insights properties to reference or clone that constant
(e.g., rhel: baseRecommendations, insights: baseRecommendations or use
[...baseRecommendations] if mutation safety is needed), keeping the existing
dynamic entry names like 'insights-tasks-conversion' intact; update any export
or object that currently defines rhel and insights to use this shared reference
so future edits only change one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx`:
- Around line 117-119: The activeToggle state (initialized via useState in
SearchPanel) is only set from isHomePage once and can become stale when
navigation changes; add a useEffect that watches isHomePage (and, if relevant,
the current bundle/context prop) and calls setActiveToggle('all' if isHomePage
else 'bundle') to keep the toggle in sync with navigation changes so the UI
reflects the current page context.

---

Nitpick comments:
In
`@src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts`:
- Around line 61-137: The rhel and insights arrays in
recommendedContentConfig.ts are duplicated; extract the common entries into a
single shared constant (e.g., baseRecommendations or COMMON_RECOMMENDATIONS) and
replace the rhel and insights properties to reference or clone that constant
(e.g., rhel: baseRecommendations, insights: baseRecommendations or use
[...baseRecommendations] if mutation safety is needed), keeping the existing
dynamic entry names like 'insights-tasks-conversion' intact; update any export
or object that currently defines rhel and insights to use this shared reference
so future edits only change one place.

In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx`:
- Around line 204-205: The search handler is re-fetching quickstarts via
fetchAllData even when allQuickStarts is already loaded; update the logic in
SearchPanel (the spots using fetchAllData to get quickStarts) to first check the
existing allQuickStarts state and reuse it if non-empty, only calling
fetchAllData(chrome.auth.getUser, {}) to obtain quickStarts when allQuickStarts
is empty or undefined; apply this change to the occurrence around the const [,
quickStarts] = await fetchAllData(...) and the duplicate block referenced (the
second occurrence around lines 383–390) so searches use cached allQuickStarts
and avoid redundant network requests.
- Around line 405-419: When showBundleContent is true the code returns curated
items as soon as resolveRecommendedItems(curatedItems, allQuickStarts) yields
any results, which can leave the returned list shorter than
RECOMMENDED_CONTENT_LIMIT; change the logic in the showBundleContent branch
(using bundleRecommendedContent[bundleId], bundleId, resolveRecommendedItems and
allQuickStarts) to, after resolving curated items, call
buildFallbackRecommendedContent(allQuickStarts, true) and append fallback items
(skipping duplicates by id or unique key) until the combined list reaches
RECOMMENDED_CONTENT_LIMIT, then return that topped-up list; apply the same
topping-up + de-duplication behavior when defaultResolved (from
defaultRecommendedContent) is non-empty so both curated and default flows fill
to the configured limit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d01dfd42-7593-46ae-88ae-b2a52ba50f4a

📥 Commits

Reviewing files that changed from the base of the PR and between 5e6efdb and 3e2b59f.

📒 Files selected for processing (2)
  • src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx
  • src/components/HelpPanel/HelpPanelTabs/SearchPanel/recommendedContentConfig.ts

Comment on lines +117 to 119
const [activeToggle, setActiveToggle] = useState<string>(
isHomePage ? 'all' : 'bundle'
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Sync recommended-scope toggle when bundle context changes.

Line [117] initializes activeToggle from isHomePage only once. If the panel stays mounted across navigation, the toggle can remain stale and show the wrong scope by default.

Proposed fix
   const [activeToggle, setActiveToggle] = useState<string>(
     isHomePage ? 'all' : 'bundle'
   );
+
+  useEffect(() => {
+    setActiveToggle(isHomePage ? 'all' : 'bundle');
+  }, [isHomePage, bundleId]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [activeToggle, setActiveToggle] = useState<string>(
isHomePage ? 'all' : 'bundle'
);
const [activeToggle, setActiveToggle] = useState<string>(
isHomePage ? 'all' : 'bundle'
);
useEffect(() => {
setActiveToggle(isHomePage ? 'all' : 'bundle');
}, [isHomePage, bundleId]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HelpPanel/HelpPanelTabs/SearchPanel/SearchPanel.tsx` around
lines 117 - 119, The activeToggle state (initialized via useState in
SearchPanel) is only set from isHomePage once and can become stale when
navigation changes; add a useEffect that watches isHomePage (and, if relevant,
the current bundle/context prop) and calls setActiveToggle('all' if isHomePage
else 'bundle') to keep the toggle in sync with navigation changes so the UI
reflects the current page context.

Copy link
Copy Markdown
Collaborator

@apinkert apinkert left a comment

Choose a reason for hiding this comment

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

this looks good to me 👍

@CodyWMitchell CodyWMitchell merged commit bbfad5d into RedHatInsights:master Mar 5, 2026
9 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